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 ofmatplotlib
, especially in real-time area: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: