清除所有数据并 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_())
我正在使用 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_())