I have a program with rapid animations which works perfectly under pygame, and for technical reasons, I need to do the same using only matplotlib or an other widespread modu
If you just need to animate a matplotlib
canvas the animation framework is the answer. There's a simple example here that does basically what you ask.
If this is going to be part of a more complex application you probably want finer control over a specific backend.
Here's a quick attempt using Qt
loosely based on this matplotlib example.
It's using a QTimer
for the updates, probably there's also some idle callback in Qt
you could attach to.
import sys
import numpy as np
import matplotlib as mpl
mpl.use('qt5agg')
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from PyQt5 import QtWidgets, QtCore
size = (400, 400)
class GameCanvas(FigureCanvas):
def __init__(self, parent=None, width=5, height=4, dpi=100):
fig = Figure(figsize=(width, height), dpi=dpi)
self.axes = fig.gca()
self.init_figure()
FigureCanvas.__init__(self, fig)
self.setParent(parent)
timer = QtCore.QTimer(self)
timer.timeout.connect(self.update_figure)
timer.start(10)
def gen_frame(self):
return np.random.randint(0,0xfffff,size)
def init_figure(self):
self.img = self.axes.imshow(self.gen_frame())
def update_figure(self):
self.img.set_data(self.gen_frame())
self.draw()
class ApplicationWindow(QtWidgets.QMainWindow):
def __init__(self):
QtWidgets.QMainWindow.__init__(self)
self.main_widget = QtWidgets.QWidget(self)
dc = GameCanvas(self.main_widget, width=5, height=4, dpi=100)
self.setCentralWidget(dc)
def fileQuit(self):
self.close()
def closeEvent(self, ce):
self.fileQuit()
app = QtWidgets.QApplication(sys.argv)
appw = ApplicationWindow()
appw.show()
sys.exit(app.exec_())
One thing you should be careful with is that imshow
computes the image normalization on the first frame. In the subsequent frames it's calling set_data
so the normalization stays the same. If you want to update it you can call imshow
instead (probably slower). Or you could just fix it manually with vmin
and vmax
in the first imshow
call and provide properly normalized frames.