2017-08-29 163 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