Matplotlib,使用 imshow 更快地刷新图像
Matplotlib, refresh image with imshow faster
我正在做一个项目,我必须在 GUI 的 window 上绘制 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)。
我希望有人能帮我提供一些线索来改进我的代码。
非常感谢您!
Matplotlib 可以生成具有出版质量的图,但不幸的是它不太适合实时绘图和视频。
如果不是严格要求,请考虑使用 pyqtgraph
module。它与 pyqt5 配合良好,旨在弥补 matplotlib
的缺点,尤其是在实时领域:
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)
它还有其他(可选)功能,例如感兴趣区域、归一化和直方图绘制。
此代码可以在我的笔记本电脑上产生约 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_())
我正在做一个项目,我必须在 GUI 的 window 上绘制 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)。
我希望有人能帮我提供一些线索来改进我的代码。 非常感谢您!
Matplotlib 可以生成具有出版质量的图,但不幸的是它不太适合实时绘图和视频。
如果不是严格要求,请考虑使用 pyqtgraph
module。它与 pyqt5 配合良好,旨在弥补 matplotlib
的缺点,尤其是在实时领域:
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)
它还有其他(可选)功能,例如感兴趣区域、归一化和直方图绘制。
此代码可以在我的笔记本电脑上产生约 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_())