【发布时间】:2018-10-02 09:42:04
【问题描述】:
我正在使用 matplotlib backend_qt5agg 处理将 matplotlib 画布绘制到 qt 窗口中。用户可以在绘图上绘制矩形(matplotlib.patches.Rectangle 类型),我通过调用canvas.draw() 方法显示矩形。如果画布包含大量数据,此方法可能会很慢,我想加快速度。
寻找解决方案,我在backend_qt5agg 手册中发现存在一个名为drawRectangle(rect) 的方法。希望此方法可以仅绘制补丁而不重绘整个画布,我尝试使用矩形补丁作为输入来调用此方法。所以我打电话给canvas.drawRectangle(my_rect),而不是打电话给canvas.draw()。这不会画任何东西。
不幸的是,backend_qt5agg 手册纯粹是记录在案的。所以我的问题是:drawRectangle 方法是如何工作的,它是否应该比重绘整个画布更好?
最小的例子(当鼠标点击并在画布内移动时显示一个矩形)(只需将self.canvas.draw() 更改为on_motion 内的self.canvas.drawRectangle(self.rect) 以测试drawRectangle 方法):
import sys
import matplotlib
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.patches import Rectangle
class MainWindow(QtW.QMainWindow):
def __init__(self):
super().__init__()
self.setWindowTitle('MyWindow')
self._main = QtW.QWidget()
self.setCentralWidget(self._main)
# Set canvas properties
self.fig = matplotlib.figure.Figure(figsize=(5,5))
self.canvas = FigureCanvasQTAgg(self.fig)
self.ax = self.fig.add_subplot(1,1,1)
self.rect = Rectangle((0,0), 0.2, 0.2, color='k', fill=None, alpha=1)
self.ax.add_patch(self.rect); self.rect.set_visible(False)
self.canvas.draw()
# set Qlayout properties and show window
self.gridLayout = QtW.QGridLayout(self._main)
self.gridLayout.addWidget(self.canvas)
self.setLayout(self.gridLayout)
self.show()
# connect mouse events to canvas
self.fig.canvas.mpl_connect('button_press_event', self.on_click)
self.fig.canvas.mpl_connect('motion_notify_event', self.on_motion)
def on_click(self, event):
if event.button == 1 or event.button == 3:
# left or right click: get the x and y coordinates
if event.inaxes is not None:
self.xclick = event.xdata
self.yclick = event.ydata
self.on_press = True
def on_motion(self, event):
# draw the square
if event.button == 1 or event.button == 3 and self.on_press == True:
if (self.xclick is not None and self.yclick is not None):
x0, y0 = self.xclick, self.yclick
x1, y1 = event.xdata, event.ydata
if (x1 is not None or y1 is not None):
self.rect.set_width(x1 - x0)
self.rect.set_height(y1 - y0)
self.rect.set_xy((x0, y0))
self.rect.set_visible(True)
self.canvas.draw() # self.canvas.drawRectangle(self.rect)
if __name__ == '__main__':
app = QtCore.QCoreApplication.instance()
if app is None: app = QtW.QApplication(sys.argv)
win = MainWindow()
app.aboutToQuit.connect(app.deleteLater)
app.exec_()
【问题讨论】:
-
从source code 看来,此函数旨在绘制当您在交互式窗口中放大图形的一部分时显示的虚线矩形。
-
@Isma 我加了一个例子
-
@DizietAsahi 感谢您指出这一点,但我仍然不清楚该方法的使用。
rect输入应该是什么? -
@Isma,当鼠标在画布内按下并移动时应该显示矩形
标签: python matplotlib canvas pyqt