Matplotlib,使用 imshow 更快地刷新图像 [英] Matplotlib, refresh image with imshow faster

查看:165
本文介绍了Matplotlib,使用 imshow 更快地刷新图像的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在做一个项目,我必须在 GUI 窗口上绘制 320*250 像素的图像,如果可能的话,每秒绘制 60 次.所以我尝试使用 ma​​tplotlib 2.0.2Python 3.6PyQt5(因为我开始了解这些工具并在另一个项目上工作)与此),以下列方式:

导入系统、随机、matplotlib从 PyQt5 导入 QtCore、QtGui、QtWidgetsmatplotlib.use('Qt5Agg')从 matplotlib.backends.backend_qt5agg 导入 FigureCanvasQTAgg 作为 FigureCanvas导入 matplotlib.pyplot 作为 plt类 SecondWindow(QtWidgets.QWidget):def __init__(self, parent=None):super(SecondWindow, self).__init__(parent)self.setupUi(self)def setupUi(self, Form):Form.setObjectName("表单")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):打印(self.count)self.count = 0def majFigure(self):self.count = self.count + 1self.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()定义初始化图(自我):self.plot = self.axes.imshow([[random.random() for x in range(1,320)] for y in range(1,250)],interpolation='none')self.count = 0self.canvas.draw()def closeEvent(self, event):self.timer.stop()如果 __name__ == '__main__':app = QtWidgets.QApplication(sys.argv)表单 = SecondWindow()表单.show()sys.exit(app.exec_())

我进行了优化,就像我可以关闭插值,并且只绘制一次图形,但使用此代码,程序每秒仅刷新图形 20 次,而计时器正确设置为 16 毫秒(1/60Hz).

我希望有人可以帮助我给我一些改进代码的线索.非常感谢!

解决方案

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

如果不是严格要求,请考虑使用 pyqtgraph 模块.它与 pyqt5 配合良好,旨在弥补 matplotlib 的缺点,尤其是在实时领域:

<块引用>

如果您正在做任何需要快速绘图更新、视频或实时交互的事情,matplotlib 不是最佳选择.这是(在我看来)matplotlib 最大的弱点

(来自 pyqtgraph 站点)

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

此代码可以在我的笔记本电脑上产生 ~160 FPS(禁用直方图):

导入系统、随机、matplotlib从 PyQt5 导入 QtCore、QtGui、QtWidgets将 pyqtgraph 导入为 pg将 numpy 导入为 np类 SecondWindow(QtWidgets.QWidget):def __init__(self, parent=None):super(SecondWindow, self).__init__(parent)self.setupUi(self)def setupUi(self, Form):Form.setObjectName("表单")Form.resize(800, 600)self.im_widget = pg.ImageView(self)# 取消隐藏直方图的注释# 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):打印(self.count)self.count = 0def majFigure(self):self.count = self.count + 1# numpy random.rand 也比列表理解快得多数据 = np.random.rand(320, 250)self.im_widget.setImage(data)定义初始化图(自我):self.count = 0self.im_widget.show()def closeEvent(self, event):self.timer.stop()如果 __name__ == '__main__':app = QtWidgets.QApplication(sys.argv)表单 = SecondWindow()表单.show()sys.exit(app.exec_())

I am working on a project on which I have to plot an image of 320*250 pixels and this 60 times per second if possible, on a window of a GUI. So I try to do this with matplotlib 2.0.2, Python 3.6 and PyQt5 (because I begin to know these tools and work on another project with this), in the following way :

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

I optimized like I can turning off the interpolation, and drawing only once the figure, but with this code the program refresh the figure only 20 times per second whereas the timer is correctly set to 16ms (1/60Hz).

I hope someone can help me giving me some clues to improve my code. I thank you in advance a lot !

解决方案

Matplotlib produces publication quality plots but unfortunately it's not quite suitable for real-time plotting and videos.

If it's not a strict requirement, consider using pyqtgraph module. It plays well with pyqt5 and designed to cover shortcomings of matplotlib, especially in real-time area:

If you are doing anything requiring rapid plot updates, video, or realtime interactivity, matplotlib is not the best choice. This is (in my opinion) matplotlib's greatest weakness

(from pyqtgraph site)

It also got additional (optional) features like Region-of-Interest, normalization and histogram plotting.

This code can produce ~160 FPS (with histogram disabled) on my laptop:

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

这篇关于Matplotlib,使用 imshow 更快地刷新图像的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆