2017-08-29 89 views
2

我正在开发一个项目,在该项目上我必须在GUI的窗口上绘制320 * 250像素的图像,并且如果可能的话,每秒显示60次。所以,我尝试用matplotlib 2.0.2Python来做到这一点3.6PyQt5(因为我开始知道这些工具和与此另一个项目工作),以下列方式:Matplotlib,使用imshow更快地刷新图像

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

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

我希望有人能帮我给我一些提高我的代码的线索。 我非常感谢你!

+1

你吃过看看[matplotlib的'animation'模块(https://matplotlib.org/api/ animation_api.html)? – Paul

+0

还没有,我现在回来给你我的新fps。 –

+0

仅供参考,使用'numpy.random.random((250,320))'代替循环创建图像,在我的机器上提供了10-15fps的提升 – user3419537

回答

3

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

如果不是严格的要求,请考虑使用pyqtgraph module。它与pyqt5打得很好,旨在覆盖matplotlib缺点,尤其是在实时区域:

如果你正在做的任何事情需要快速的情节更新,视频,或实时互动,matplotlib是不是最好的选择。 这是(在我看来)matplotlib最大的弱点

(from pyqtgraph site) 

这也得到了额外的(可选)功能,如地区的兴趣,规范化和直方图绘制。

此代码可以生成〜160 FPS(与直方图禁用)我的笔记本电脑:

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

我的电脑上的60 fps确实速度更快。但我不知道pyqtgraph。将matplotlib(标签,缩放,光标等)作为图形处理很容易吗? –

+1

事实上,它是matplotlib的漂亮和pyqtgraph的速度之间的折衷。虽然pyqtgraph是高度可配置的,但我未能创建像matplotlib这样的漂亮地块。至于你的问题 - 诸如标签,缩放,光标等是完全可配置的。我建议你安装pyqtgraph并运行其展示,然后决定:'python -m pyqtgraph.examples' – 9dogs