python - 在PyQt应用程序中嵌入Matplolib / Basemap

时间:2017-09-25 23:22:59

标签: python matplotlib

我正在尝试编写一个简单的应用程序,该应用程序读取KML文件并将数据绘制到Matplotlib / Basemap上 - 那种可怜的人Google Earth"可以离线使用,以便快速查看地理空间上的数据分布。

目前,我的问题是将Basemap嵌入到用户界面中。下面的代码创建应用程序,但它不显示地图,而只显示一对轴。

import warnings
import sys
import numpy as np
from PyQt4 import QtCore, QtGui
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from mpl_toolkits.basemap import Basemap
warnings.filterwarnings("ignore")

class MyMplCanvas(FigureCanvas):
    def __init__(self, parent=None, width=5, height=4, dpi=100):
        fig = Figure(figsize=(width, height), dpi=dpi)
        self.axes = fig.add_subplot(111)

        FigureCanvas.__init__(self, fig)
        self.setParent(parent)

        FigureCanvas.setSizePolicy(self,
                                   QtGui.QSizePolicy.Expanding,
                                   QtGui.QSizePolicy.Expanding)
        FigureCanvas.updateGeometry(self)

        m = Basemap()
        m.drawcoastlines(color='#777799')
        m.drawcountries(color='#ccccee')
        m.drawmapboundary()
        m.bluemarble()

class MainWindow(QtGui.QMainWindow):
    def __init__(self, parent = None):
        QtGui.QMainWindow.__init__(self)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)

        self.fileMenu = QtGui.QMenu("&File", self)
        self.fileMenu.addAction("Open...", self.fileOpen,
                                QtCore.Qt.CTRL + QtCore.Qt.Key_O)
        self.fileMenu.addSeparator()
        self.fileMenu.addAction("&Quit", self.fileQuit,
                                 QtCore.Qt.CTRL + QtCore.Qt.Key_Q)
        self.menuBar().addMenu(self.fileMenu)

        self.statusBar().setSizeGripEnabled(True)
        self.statusBar().showMessage("Ready")

        self.items = QtGui.QDockWidget("Layers", self)
        self.items.setFloating(False)
        self.items.setFeatures(self.items.NoDockWidgetFeatures)

        self.listWidget = QtGui.QListWidget()
        self.listWidget.addItem("file1")
        self.listWidget.addItem("file2")
        self.listWidget.addItem("file3")      
        self.items.setWidget(self.listWidget)

        self.main_widget = QtGui.QWidget(self)
        l = QtGui.QVBoxLayout(self.main_widget)
        sc = MyMplCanvas(self.main_widget, width=5, height=4, dpi=100)
        l.addWidget(sc)
        self.main_widget.setFocus()
        self.setCentralWidget(self.main_widget)
        self.setGeometry(100,100,650,350)
        self.addDockWidget(QtCore.Qt.LeftDockWidgetArea, self.items)
        self.setWindowTitle("Poor's Man KML Viewer")
        self.show()

    def fileOpen(self):
        filename = unicode(QtGui.QFileDialog.getSaveFileName(self, 
                        "Open file", "", 
                        "KML files (*.kml)"))
        if filename:
            self.listWidget.addItem(filename)

    def fileQuit(self):
        self.close()

    def closeEvent(self, ce):
        self.fileQuit()

def main():
    app = QtGui.QApplication(sys.argv)
    main = MainWindow()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main()

将Matplotlib图嵌入到PyQt应用程序中有很好的例子,但我找不到任何考虑底图。

任何人都可以帮我一把吗?

提前致谢!

1 个答案:

答案 0 :(得分:1)

我想说你错过告诉底图它应该驻留在哪个轴上:

m = Basemap(..., ax=self.axes)

我还建议不要通过python函数的名称来调用变量。即使用m代替map。  虽然这在这里没有问题,但在其他情况下这是一个容易受到监督的问题。

如果不使用ax参数,Basemap会创建自己的图形或在pyplot中获取可用的matplotlib轴。由于在嵌入式情况下,您根本不想使用pyplot,因此需要为底图指定特定的轴。