清除所有数据并 canvas 重绘底图

Clearing all data and canvas to redraw Basemap

我正在使用 Designer 制作的 Qt 表单上的底图绘制用户选择的数据。地图第一次正确显示,但不清除和绘制第二个数据集。我正在使用 plt.close("all")、figure.clear() 和 map_canvas.draw() 来清除所有对象,但它没有刷新地图。我错过了什么?

代码如下:

from PyQt5 import uic, QtWidgets
from PyQt5.QtWidgets import QVBoxLayout

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
import matplotlib.pyplot as plt, numpy as np
from mpl_toolkits.basemap import Basemap
import sys

qtCreatorFile = ('map_debug_form.ui')

LandingPageUI, LandingPageBase = uic.loadUiType(qtCreatorFile)

class searchApp(LandingPageBase, LandingPageUI):

    def __init__(self, parent=None):
        QtWidgets.QMainWindow.__init__(self)
        LandingPageBase.__init__(self)
        self.setupUi(self)    

        def plotMap(latlongs):            
            plt.close("all")            
            
            try:
                self.map_figure.clear()
            except Exception as e:
                print("map figure doesn't exist")

            self.map_figure = plt.figure(figsize=(20,20))
            self.map_canvas = FigureCanvas(self.map_figure)
            self.map_toolbar = NavigationToolbar(self.map_canvas, self)

            layout = QVBoxLayout() 
            layout.addWidget(self.map_toolbar)
            layout.addWidget(self.map_canvas)
            layout.setSpacing(0)
            self.mapWindow.setLayout(layout)      

            lons=[]
            lats=[]    
            
            for item in latlongs:
                if item[0] < 0:
                    tempLon = 360+item[0]
                else:
                    tempLon = item[0]
                    
                lons.append(tempLon)
                lats.append(item[1])
        
            m =Basemap(llcrnrlon=(min(lons)-15),llcrnrlat=(min(lats)-15),urcrnrlon=(max(lons)+15),urcrnrlat=(max(lats)+15),projection='mill',resolution = 'l')

            x, y = m(lons, lats)
            m.drawcoastlines(linewidth=.75)
            m.fillcontinents(color='0.8')
            m.drawparallels(np.arange(-80,81,5),labels=[1,1,0,0])
            m.drawmeridians(np.arange(0,360,10),labels=[0,0,0,1])
            
            m.scatter(x,y,10,marker='o',color='r', zorder=10,  alpha=0.7,  picker=True)
            self.map_figure.subplots_adjust(left=0, right=1, top=1, bottom=0.04)
            self.map_canvas.draw()         # refresh canvas
            self.map_canvas.flush_events() # flush the GUI events                
            
        self.btnMap1.clicked.connect(lambda: plotMap([[-167.7742, 54.20214], [-167.7742, 54.20214], [-164.24091, 54.9311], [-163.9388, 54.4394], [-160.59821, 54.86025]]))
        self.btnMap2.clicked.connect(lambda: plotMap([[-172.7829, 50.55793], [-172.7829, 50.55793], [-172.7829, 50.55793], [-169.78149, 50.6384], [-169.78149, 50.6384]]))


if __name__ == "__main__":

    app=QtWidgets.QApplication.instance() 
    if not app: 
         app = QtWidgets.QApplication(sys.argv)

    window = searchApp()
    window.show()
    sys.exit(app.exec_())

您不必每次都创建一个新绘图,而是将 AxesSubplot 作为底图的 ax 参数传递给它。

import sys

from PyQt5 import QtWidgets

from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.backends.backend_qt5agg import NavigationToolbar2QT as NavigationToolbar
from matplotlib.figure import Figure

import numpy as np

from mpl_toolkits.basemap import Basemap


class MainWindow(QtWidgets.QMainWindow):
    def __init__(self, parent=None):
        super().__init__(parent)

        button1 = QtWidgets.QPushButton("button1")
        button2 = QtWidgets.QPushButton("button2")

        self.map_canvas = FigureCanvas(Figure(figsize=(20, 20)))
        self.map_toolbar = NavigationToolbar(self.map_canvas, self)

        central_widget = QtWidgets.QWidget()
        self.setCentralWidget(central_widget)
        lay = QtWidgets.QGridLayout(central_widget)
        lay.addWidget(button1, 0, 0)
        lay.addWidget(button2, 0, 1)
        lay.addWidget(self.map_canvas, 1, 0, 1, 2)

        self.addToolBar(self.map_toolbar)

        button1.clicked.connect(self.handle_clicked_1)
        button2.clicked.connect(self.handle_clicked_2)

        self.ax = self.map_canvas.figure.subplots()
        self.ax.set_axis_off()

    def handle_clicked_1(self):

        self.update_plot(
            [
                [-167.7742, 54.20214],
                [-167.7742, 54.20214],
                [-164.24091, 54.9311],
                [-163.9388, 54.4394],
                [-160.59821, 54.86025],
            ]
        )

    def handle_clicked_2(self):

        self.update_plot(
            [
                [-172.7829, 50.55793],
                [-172.7829, 50.55793],
                [-172.7829, 50.55793],
                [-169.78149, 50.6384],
                [-169.78149, 50.6384],
            ]
        )

    def update_plot(self, latlongs):
        self.ax.clear()

        lons = []
        lats = []

        for item in latlongs:
            longitude, latitude = item
            lons.append(360 + longitude if longitude < 0 else longitude)
            lats.append(latitude)

        m = Basemap(
            llcrnrlon=(min(lons) - 15),
            llcrnrlat=(min(lats) - 15),
            urcrnrlon=(max(lons) + 15),
            urcrnrlat=(max(lats) + 15),
            projection="mill",
            resolution="l",
            ax=self.ax,
        )
        x, y = m(lons, lats)
        m.drawcoastlines(linewidth=0.75)
        m.fillcontinents(color="0.8")
        m.drawparallels(np.arange(-80, 81, 5), labels=[1, 1, 0, 0])
        m.drawmeridians(np.arange(0, 360, 10), labels=[0, 0, 0, 1])
        m.scatter(x, y, 10, marker="o", color="r", zorder=10, alpha=0.7, picker=True)

        self.map_canvas.draw()


if __name__ == "__main__":

    app = QtWidgets.QApplication.instance()
    if app is None:
        app = QtWidgets.QApplication(sys.argv)

    window = MainWindow()
    window.show()

    sys.exit(app.exec_())