Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/meteor/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python-PyQt-matplotlib:drawRectangle方法_Python_Matplotlib_Canvas_Pyqt - Fatal编程技术网

Python-PyQt-matplotlib:drawRectangle方法

Python-PyQt-matplotlib:drawRectangle方法,python,matplotlib,canvas,pyqt,Python,Matplotlib,Canvas,Pyqt,我使用matplotlib后端_qt5agg来处理将matplotlib画布绘制到qt窗口中的操作。用户可以在绘图上绘制矩形(类型为matplotlib.patches.Rectangle),我通过调用canvas.draw()方法来显示矩形。如果画布包含大量数据,那么这种方法可能会非常慢,我想加快速度 我在backend_qt5agg手册中找到了一个名为drawRectangle(rect)的方法来寻找解决方案。希望这个方法可以只绘制补丁而不重新绘制整个画布,我尝试使用矩形补丁作为输入调用这个

我使用matplotlib
后端_qt5agg
来处理将matplotlib画布绘制到qt窗口中的操作。用户可以在绘图上绘制矩形(类型为
matplotlib.patches.Rectangle
),我通过调用
canvas.draw()
方法来显示矩形。如果画布包含大量数据,那么这种方法可能会非常慢,我想加快速度

我在
backend_qt5agg
手册中找到了一个名为
drawRectangle(rect)
的方法来寻找解决方案。希望这个方法可以只绘制补丁而不重新绘制整个画布,我尝试使用矩形补丁作为输入调用这个方法。因此我调用了
canvas.drawRectangle(my_rect)
,而不是调用
canvas.draw()
。这画不出任何东西

不幸的是,
backend\u qt5agg
手册纯粹是文档化的。所以我的问题是:
drawRectangle
方法是如何工作的,它的性能是否应该比重画整个画布更好

最简单的示例(鼠标单击并在画布内移动时显示一个矩形)(只需将
self.canvas.draw()
更改为
self.canvas.drawRectangle(self.rect)
inside
on\u motion
以测试
drawRectangle
方法):


您可以使用已包含在matplotlib.widgets中的
RectangleSelector
小部件,而不是自己添加矩形

下面是一个例子,您需要对其进行润色并使其适应您的需要,但我希望它能让您继续:

import sys
import matplotlib
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.widgets import RectangleSelector


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.canvas.draw()

        self.rs = RectangleSelector(self.ax, self.line_select_callback,
                                                drawtype='box', useblit=True,
                                                button=[1, 3],  # don't use middle button
                                                minspanx=5, minspany=5,
                                                spancoords='pixels',
                                                interactive=True)

        # 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)

    def on_click(self, event):
        if event.button == 1 or event.button == 3 and not self.rs.active:
            self.rs.set_active(True)
        else:
            self.rs.set_active(False)

    def line_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        print("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
        print(" The button you used were: %s %s" % (eclick.button, erelease.button))

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_()

参考:

您可以使用已作为matplotlib.widgets一部分包含的
RectangleSelector
小部件,而不是自己添加矩形

下面是一个例子,您需要对其进行润色并使其适应您的需要,但我希望它能让您继续:

import sys
import matplotlib
from PyQt5 import QtCore
import PyQt5.QtWidgets as QtW
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg
from matplotlib.widgets import RectangleSelector


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.canvas.draw()

        self.rs = RectangleSelector(self.ax, self.line_select_callback,
                                                drawtype='box', useblit=True,
                                                button=[1, 3],  # don't use middle button
                                                minspanx=5, minspany=5,
                                                spancoords='pixels',
                                                interactive=True)

        # 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)

    def on_click(self, event):
        if event.button == 1 or event.button == 3 and not self.rs.active:
            self.rs.set_active(True)
        else:
            self.rs.set_active(False)

    def line_select_callback(self, eclick, erelease):
        x1, y1 = eclick.xdata, eclick.ydata
        x2, y2 = erelease.xdata, erelease.ydata
        print("(%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1, y1, x2, y2))
        print(" The button you used were: %s %s" % (eclick.button, erelease.button))

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_()

参考:

从中可以看出,此函数的作用是绘制在交互式窗口中放大部分图形时显示的虚线矩形。请添加一个。@Isma我添加了一个example@DizietAsahi谢谢你指出这一点,但我仍然不清楚该方法的用途。
rect
input应该是什么?@Isma,当鼠标从画布中按下并移动时,矩形应该显示出来。这个函数似乎是为了绘制虚线矩形,当您在交互窗口中放大图形的一部分时,它会显示出来。请,添加一个。@Isma我添加了一个example@DizietAsahi谢谢你指出这一点,但我仍然不清楚该方法的用途。
rect
input应该是什么?@Isma,当鼠标在canvasThanks中按下并移动时,应该显示矩形。例如,您的选择解决方案非常优雅。另一方面,我的问题更一般。例如,选择后,我希望一个矩形保持在画布上,假设我希望根据其他用户操作(例如QPushButton)更改矩形属性(例如线条或颜色)。那样的话,我得重新画画布。我的问题仍然是:是否可以在不重新绘制整个画布的情况下修改该矩形?是的,您可以,您做得不错,但是您需要传递一个列表而不是一个矩形,例如self.canvas.drawRectangle([x0,y0,x1,y1]),谢谢您的回答,但是如果我使用
self.canvas.drawRectangle([x0,y0,x1,y1]))
在我的代码中,它没有绘制任何东西,而不是
self.canvas.draw()
。是的,我知道。在我的示例x0、y0等中。。是鼠标事件给出的实值,如果我使用
self.canvas.draw()
绘制画布,则实值有效,但如果使用
self.canvas.drawRectangle([x0,y0,x1,y1])
则无效。你测试过了吗?谢谢你的例子,你的选择方案非常优雅。另一方面,我的问题有点笼统。例如,选择后,我希望一个矩形保持在画布上,假设我希望根据其他用户操作(例如QPushButton)更改矩形属性(例如线条或颜色)。那样的话,我得重新画画布。我的问题仍然是:是否可以在不重新绘制整个画布的情况下修改该矩形?是的,您可以,您做得不错,但是您需要传递一个列表而不是一个矩形,例如self.canvas.drawRectangle([x0,y0,x1,y1]),谢谢您的回答,但是如果我使用
self.canvas.drawRectangle([x0,y0,x1,y1]))
在我的代码中,它没有绘制任何东西,而不是
self.canvas.draw()
。是的,我知道。在我的示例x0、y0等中。。是鼠标事件给出的实值,如果我使用
self.canvas.draw()
绘制画布,则实值有效,但如果使用
self.canvas.drawRectangle([x0,y0,x1,y1])
则无效。你测试过了吗?