使用pyqtgraph实时绘制许多子图

时间:2018-10-28 13:29:43

标签: python python-3.x pyqtgraph

我使用了this问题,并试图用它来完成许多子图的实时绘制。

不幸的是,我很难理解代码,因此我无法根据自己的需要对其进行更改。

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

enter image description here

代码如下:

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

有人可以告诉我我在做什么错吗?

1 个答案:

答案 0 :(得分: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_())

enter image description here

更新:

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)

enter image description here

更新

如果您想在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_())