Matplotlib equivalent of pygame flip

前端 未结 4 549
天涯浪人
天涯浪人 2021-01-05 05:21

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

4条回答
  •  小蘑菇
    小蘑菇 (楼主)
    2021-01-05 06:10

    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.

提交回复
热议问题