【问题标题】:Trying to optimize pyqtgraph plotting尝试优化 pyqtgraph 绘图
【发布时间】:2017-03-11 19:18:27
【问题描述】:

我正在尝试在 pyqtgraph 中不使用 pg.PolyLineROI() 来绘制多边形。我的目标是能够在下面显示的代码中使用大型数据集来代替“数据”。 PolyLineROI() 的问题是我不需要句柄或事件,因此加载大量数据需要很长时间,而且资源浪费在不需要的功能上。

我尝试过使用 QPainter 和 QPen,但我无法获得任何有用的东西,所以我被卡住了。有什么想法吗?

编辑的代码试图合并来自 segFaultCoder 的示例

from PyQt4 import QtCore, QtGui
import pyqtgraph as pg
import sys

class plotwindow(QtGui.QMainWindow):
        def setupUi(self, MainWindow):

            self.centralwidget = QtGui.QWidget(MainWindow)
            MainWindow.resize(1900, 1000)

            self.qt = pg.GraphicsView(MainWindow)
            self.qt.setGeometry(QtCore.QRect(0,0, 1900, 1000))
            self.qt2 = pg.GraphicsLayout()
            self.qt.setCentralItem(self.qt2)
            self.qt.show()
            self.layout = self.qt2.addLayout()
            self.qt3 = self.layout.addViewBox()


            self.plot()

        def plot(self): #This is looped for multiple data sets
            data = [[6,6],[6,0],[0,6],[0,0]] #changes based on data import
            self.picture = QtGui.QPicture()
            p = QtGui.QPainter(self.picture)
            p.setPen(pg.mkPen('w'))
            self.points = []
            for item in data:
                point = QtCore.QPoint(item[0], item[1])
                self.points.append(point)
            p.drawPolygon(*self.points)
            p.end()
            self.qt3.addItem(p)

    def paint(self, p, *args):
        p.drawPicture(0, 0, self.picture)

    def boundingRect(self):
        return QtCore.QRectF(self.picture.boundingRect())

if __name__ == "__main__":
    app = QtGui.QApplication(sys.argv)
    MainWindow = QtGui.QMainWindow()
    ui = plotwindow()
    ui.setupUi(MainWindow)
    MainWindow.show()
    sys.exit(app.exec_()) 

【问题讨论】:

    标签: python pyqt pyqtgraph


    【解决方案1】:

    我认为您使用 QPainter 的方法是正确的,只需查看他们的示例文件夹,您就会看到 customGraphicsItem.py。我基本上只是复制了它并用您的点替换了它们的“数据”变量,然后使用 QPainter.drawPolygon() 重写了 generatePicture() 方法。希望我所有的缩进都是正确的,我不能完全掌握在 SO 上格式化帖子的窍门。

    import pyqtgraph as pg
    from pyqtgraph import QtCore, QtGui
    
    # Create a subclass of GraphicsObject.
    # The only required methods are paint() and boundingRect() 
    # (see QGraphicsItem documentation)
    class customPolyItem(pg.GraphicsObject):
        def __init__(self, data):
            pg.GraphicsObject.__init__(self)
            self.data = data  
            self.points = []
            self.generatePicture()
    
    
        def generatePicture(self):
            # pre-computing a QPicture object allows paint() to run much more quickly, 
            # rather than re-drawing the shapes every time.
            self.picture = QtGui.QPicture()
            p = QtGui.QPainter(self.picture)
            p.setPen(pg.mkPen('w'))
            for item in self.data:
                point = QtCore.QPoint(item[0],item[1])
                self.points.append(point)
            p.drawPolygon(*self.points)
            p.end()
    
        def paint(self, p, *args):
            p.drawPicture(0, 0, self.picture)
    
        def boundingRect(self):
            # boundingRect _must_ indicate the entire area that will be drawn on
            # or else we will get artifacts and possibly crashing.
            # (in this case, QPicture does all the work of computing the bouning rect for us)
            return QtCore.QRectF(self.picture.boundingRect())
    
    data = [[6,6],[6,0],[0,6],[0,0]]
    
    item = customPolyItem(data)
    plt = pg.plot()
    plt.addItem(item)
    plt.setWindowTitle('pyqtgraph example: customPolyItem')
    
    ## Start Qt event loop unless running in interactive mode or using pyside.
    if __name__ == '__main__':
        import sys
        if (sys.flags.interactive != 1) or not hasattr(QtCore, 'PYQT_VERSION'):
            QtGui.QApplication.instance().exec_()
    

    编辑:关于你的新代码,用这个替换你的绘图方法(并删除油漆和边界矩形):

        def plot(self): #This is looped for multiple data sets
            data = [[6,6],[6,0],[0,6],[0,0]] #changes based on data import
            newCPI = customPolyItem(data) # create new instance with changed data
            self.qt3.addItem(newCPI) # add the new instance to your viewbox
    

    如果 customPolyItem 类位于单独的文件中,您将需要导入它,或者只需将整个类声明复制粘贴到您当前的 plotwindow 类下方。

    【讨论】:

    • 我一直在尝试将您的代码实现到我的循环中。我在上面编辑了我的代码以表示我目前所处的位置。我在上面编辑的代码中遇到了与在代码中调用您的类时相同的错误,所以我不确定如何继续。
    • 只是仔细查看了您的代码。请注意,在我的示例上方的 cmets 中,“customPolyItem”它是 GraphicsObject 的子类,并且正如那里所引用的那样,“paint”和“boundingrect”是“QGraphicsObject -> QGraphicsItem”方法的方法覆盖。在您的代码中,您现在不能在“QMainWindow”子类中使用这两种方法。对于每组新的“数据”,您需要创建一个 customPolyItem 实例并将其相应地添加到您的绘图/布局中,在这种情况下,customPolyItem 仍然拥有 paint 和 boundingrect 方法。
    • 查看我编辑的答案,如果有效,请务必接受答案:)
    • 我完全尝试了您所拥有的,在绘制大型数据集时,它会删除大部分数据,并在将其放置在单独的文件中并调用我的代码时仅绘制多个正方形。我将数据设置为包含 30 个点的数据集,它绘制了一个矩形。
    • 因为我不完全知道你想要完成什么,我无法解决这个问题。如果您可以发布不起作用的代码,并解释您希望它做什么,我很乐意尝试并提供帮助。如果没有更好的细节,我当然无法为您测试边界条件。您是否让它与您发布的 4 点示例一起使用?如果是这样,它会在什么时候中断?
    猜你喜欢
    • 2018-07-19
    • 2019-02-02
    • 2019-03-03
    • 2015-04-21
    • 2011-02-14
    • 2019-04-16
    • 1970-01-01
    • 2018-03-05
    • 2018-06-11
    相关资源
    最近更新 更多