代码之家  ›  专栏  ›  技术社区  ›  Mathieu Gauquelin

Matplotlib,使用imshow更快地刷新图像

  •  2
  • Mathieu Gauquelin  · 技术社区  · 7 年前

    我正在做一个项目,我必须在图形用户界面的窗口上绘制一个320*250像素的图像,如果可能的话,每秒绘制60次。所以我试着用 PyQt5 (因为我开始了解这些工具,并用它进行另一个项目的工作),方法如下:

    import sys, random, matplotlib
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    matplotlib.use('Qt5Agg')
    from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
    import matplotlib.pyplot as plt
    
    class SecondWindow(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(SecondWindow, self).__init__(parent)
            self.setupUi(self)
    
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(800, 600)
    
            self.figure = plt.figure()
            self.canvas = FigureCanvas(self.figure)
            self.axes = self.figure.add_subplot(111)
    
            self.setLayout(QtWidgets.QVBoxLayout())
            self.layout().addWidget(self.canvas)
    
            self.initialisationFigure()
    
            self.timer = QtCore.QTimer(self)
            self.timer.timeout.connect(self.majFigure)
            self.timer.start(16)
    
            self.timer2 = QtCore.QTimer(self)
            self.timer2.timeout.connect(self.NumberRefreshPerSecond)
            self.timer2.start(1000)
    
        def NumberRefreshPerSecond(self):
            print(self.count)
            self.count = 0
    
        def majFigure(self):
            self.count = self.count + 1
            self.plot.set_data([[random.random() for x in range(1, 320)] for y in range(1, 250)])
            # self.canvas.draw()
            self.axes.draw_artist(self.axes.patch)
            self.axes.draw_artist(self.plot)
            self.canvas.update()
            self.canvas.flush_events()
    
        def initialisationFigure(self):
            self.plot = self.axes.imshow([[random.random() for x in range(1,320)] for y in range(1,250)], interpolation='none')
            self.count = 0
            self.canvas.draw()
    
        def closeEvent(self, event):
            self.timer.stop()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        form = SecondWindow()
        form.show()
        sys.exit(app.exec_())
    

    我希望有人能帮我改进代码。

    1 回复  |  直到 7 年前
        1
  •  3
  •   9dogs    7 年前

    Matplotlib生成出版物质量的绘图,但不幸的是,它不太适合实时绘图和视频。

    pyqtgraph module . 它与pyqt5配合良好,旨在弥补 matplotlib

    如果您正在做任何需要快速打印更新、视频或实时交互的事情,matplotlib不是最佳选择。

    (from pyqtgraph site)
    

    它还具有其他(可选)功能,如感兴趣区域、归一化和直方图绘制。

    import sys, random, matplotlib
    from PyQt5 import QtCore, QtGui, QtWidgets
    
    import pyqtgraph as pg
    import numpy as np
    
    
    class SecondWindow(QtWidgets.QWidget):
        def __init__(self, parent=None):
            super(SecondWindow, self).__init__(parent)
            self.setupUi(self)
    
        def setupUi(self, Form):
            Form.setObjectName("Form")
            Form.resize(800, 600)
    
            self.im_widget = pg.ImageView(self)
            # uncomment to hide histogram
            # self.im_widget.ui.histogram.hide()
    
            self.setLayout(QtWidgets.QVBoxLayout())
            self.layout().addWidget(self.im_widget)
    
            self.initialisationFigure()
    
            self.timer = QtCore.QTimer(self)
            self.timer.timeout.connect(self.majFigure)
            self.timer.start(16)
    
            self.timer2 = QtCore.QTimer(self)
            self.timer2.timeout.connect(self.NumberRefreshPerSecond)
            self.timer2.start(1000)
    
        def NumberRefreshPerSecond(self):
            print(self.count)
            self.count = 0
    
        def majFigure(self):
            self.count = self.count + 1
            # numpy random.rand also much faster than list comprehension
            data = np.random.rand(320, 250)
            self.im_widget.setImage(data)
    
        def initialisationFigure(self):
            self.count = 0
            self.im_widget.show()
    
        def closeEvent(self, event):
            self.timer.stop()
    
    if __name__ == '__main__':
        app = QtWidgets.QApplication(sys.argv)
        form = SecondWindow()
        form.show()
        sys.exit(app.exec_())