【问题标题】:Live plotting of many subplots using pyqtgraph使用 pyqtgraph 实时绘制许多子图
【发布时间】:2019-04-01 14:10:22
【问题描述】:

我使用this question 并尝试使用它来快速绘制许多子图。

不幸的是,我很难理解代码,因此我很难根据需要更改它。

我想创建一个具有 10x10 像素的 2x2 矩阵的子图。现在我得到以下信息:

代码如下:

from pyqtgraph.Qt import QtCore, QtGui
import pyqtgraph as pg
import numpy as np
import time
import sys

class App(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(App, self).__init__(parent)

        #### Create Gui Elements ###########
        self.mainbox = QtGui.QWidget()
        self.setCentralWidget(self.mainbox)
        self.mainbox.setLayout(QtGui.QVBoxLayout())

        self.canvas = pg.GraphicsLayoutWidget()
        self.mainbox.layout().addWidget(self.canvas)

        self.label = QtGui.QLabel()
        self.mainbox.layout().addWidget(self.label)

        self.view = self.canvas.addViewBox()
        self.view.setAspectLocked(True)
        self.view.setRange(QtCore.QRectF(0, 0, 50, 50))

        self.img = []
        for i in range(4): 
            self.img.append(pg.ImageItem(None, border="w"))
            self.canvas.nextRow()
            self.view.addItem(self.img[i])

        self._update()

    def _update(self):
        for i in range(4):
            self.data = np.random.rand(10,10)
            self.img[i].setImage(self.data)

        QtCore.QTimer.singleShot(1, self._update)

def sensor_data(n_sensors, x_res, y_res):
    return np.random.rand(n_sensors, x_res, y_res)

if __name__ == '__main__':
    while True:
        # Get sensor data
        data = sensor_data(4, 10, 10)
        # Pass data to live plot function?

    app = QtGui.QApplication(sys.argv)
    thisapp = App()
    thisapp.show()
    sys.exit(app.exec_())

谁能告诉我我做错了什么?

【问题讨论】:

    标签: python python-3.x pyqtgraph


    【解决方案1】:

    您只构建了一个 ViewBox 并在其中添加了导致问题的项目,您必须做的是创建多个 ViewBox 并添加一个项目,如下所示:

    from pyqtgraph.Qt import QtCore, QtGui
    import pyqtgraph as pg
    import numpy as np
    
    
    class App(QtGui.QMainWindow):
        def __init__(self, parent=None):
            super(App, self).__init__(parent)
            self.mainbox = QtGui.QWidget()
            self.setCentralWidget(self.mainbox)
    
            self.canvas = pg.GraphicsLayoutWidget()
            self.label = QtGui.QLabel()
    
            lay = QtGui.QVBoxLayout(self.mainbox)
            lay.addWidget(self.canvas)
            lay.addWidget(self.label)
    
            self.img_items = []
    
            for i in range(4):
                view = self.canvas.addViewBox()
                view.setAspectLocked(True)
                view.setRange(QtCore.QRectF(0, 0, 10, 10))
                it = pg.ImageItem(None, border="w")
                view.addItem(it)
                self.img_items.append(it)
                self.canvas.nextRow()
    
            timer = QtCore.QTimer(self, interval=1)
            timer.timeout.connect(self._update)
            timer.start()
    
        def _update(self):
            for item in self.img_items:
                data = np.random.rand(10, 10)
                item.setImage(data)
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        thisapp = App()
        thisapp.show()
        sys.exit(app.exec_())
    

    更新:

    NxN

    n = 2
    for i in range(n):
        for j in range(n):
            view = self.canvas.addViewBox(i, j)
            view.setAspectLocked(True)
            view.setRange(QtCore.QRectF(0, 0, 10, 10))
            it = pg.ImageItem(None, border="w")
            view.addItem(it)
            self.img_items.append(it)
    

    更新:

    如果你想在一段时间内获取数据 True 你必须在一个新线程中进行以避免 GUI 被阻塞,你还必须给一个小睡眠以便 GUI 可以更新:

    from pyqtgraph.Qt import QtCore, QtGui
    import pyqtgraph as pg
    import numpy as np
    
    
    def sensor_data(n_sensors, x_res, y_res):
        return np.random.rand(n_sensors, x_res, y_res)
    
    
    class Thread(QtCore.QThread):
        dataChanged = QtCore.pyqtSignal(np.ndarray)
        def run(self):
            while True:
                data = sensor_data(4, 10, 10)
                self.dataChanged.emit(data)
                QtCore.QThread.msleep(10)
    
    
    class App(QtGui.QMainWindow):
        def __init__(self, parent=None):
            super(App, self).__init__(parent)
            self.mainbox = QtGui.QWidget()
            self.setCentralWidget(self.mainbox)
    
            self.canvas = pg.GraphicsLayoutWidget()
            self.label = QtGui.QLabel()
    
            lay = QtGui.QVBoxLayout(self.mainbox)
            lay.addWidget(self.canvas)
            lay.addWidget(self.label)
    
            self.img_items = []
            n = 2
    
            for i in range(n):
                for j in range(n):
                    view = self.canvas.addViewBox(i, j)
                    view.setAspectLocked(True)
                    view.setRange(QtCore.QRectF(0, 0, 10, 10))
                    it = pg.ImageItem(None, border="w")
                    view.addItem(it)
                    self.img_items.append(it)
    
        @QtCore.pyqtSlot(np.ndarray)
        def update_data(self, data):
            for i, v in enumerate(data):
                self.img_items[i].setImage(v)
    
    
    if __name__ == '__main__':
        import sys
        app = QtGui.QApplication(sys.argv)
        thisapp = App()
        thread = Thread()
        thread.dataChanged.connect(thisapp.update_data)
        thread.start()
        thisapp.show()
        sys.exit(app.exec_())
    

    【讨论】:

    • 是否可以将子图放置为马赛克?在这种情况下'2 x 2'?一般来说'n x n'?以及如何将数据从主函数提供给“_update”函数?
    • @Samuel 第一点明白了,第二点,你想每隔多久发送一次数据?以及如何获取数据?
    • @Samuel 的想法是,如果您有实时绘图,您可以在 _update 中获取数据,例如:def _update(self): for item in self.img_items: data = foo_get_data(i) item.setImage(data)
    • 我有传感器数据,我保存在一个类型为“(n_sensors,x_res,y_res)”的numpy数组中。在上面的例子中,我有 n_sensors=4 和 x_res = y_res = 10。我在主函数中调用该数据流,我想将它传递给绘图过程。这发生在 main 函数的 while 循环中。我希望这会有所帮助。
    • @Samuel do not use while True,忘了它,那会阻塞 GUI,告诉我你是如何获取数据的,即读取数据的函数并告诉你正确的方法去做吧。
    猜你喜欢
    • 2018-03-05
    • 2019-02-02
    • 2017-12-16
    • 2021-12-27
    • 2012-10-22
    • 2019-07-24
    • 2017-05-31
    • 2013-07-30
    • 2019-02-13
    相关资源
    最近更新 更多