我正在开发一个项目,我必须在GUI窗口上绘制320 * 250像素的图像,如果可能的话,每秒60次。所以我尝试使用 matplotlib 2.0.2 , Python 3.6 和 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_())
我进行了优化,就像我可以关闭插值,并且仅绘制一次图形,但是使用此代码,程序每秒仅刷新图形20次,而计时器正确设置为16ms(1 / 60Hz)。
我希望有人可以帮我提供一些改进代码的线索。 我提前感谢你了!
答案 0 :(得分: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_())