Skip to content Skip to sidebar Skip to footer

Getting Blitting To Work In Funcanimation Embedded In Pyqt4 Gui

Starting with the working Matplotlib animation code shown below, my goal is to embed this animation (which is just a circle moving across the screen) within a PyQT4 GUI. import mat

Solution 1:

After looking at the source code of the animation module, I realized that there is an error in the Animation class (the dictionary bg_cache is empty, when it is accessed for the first time with blitting switched on).

This is fixed in the git version of matplotlib; however, in the most recent stable version 1.5.1, the bug is still present. You can either fix the bug in the matplotlib code itself or you can make a subclass to FuncAnimation. I chose that way, because it should still work after updating matplotlib.

from matplotlib import animation

classMyFuncAnimation(animation.FuncAnimation):
    """
    Unfortunately, it seems that the _blit_clear method of the Animation
    class contains an error in several matplotlib verions
    That's why, I fork it here and insert the latest git version of
    the function.
    """def_blit_clear(self, artists, bg_cache):
        # Get a list of the axes that need clearing from the artists that# have been drawn. Grab the appropriate saved background from the# cache and restore.
        axes = set(a.axes for a in artists)
        for a in axes:
            if a in bg_cache: # this is the previously missing line
                a.figure.canvas.restore_region(bg_cache[a])

Then, simpy use MyFuncAnimation instead of animation.FuncAnimation.

Took me a while to figure it out, but I hope it helps anybody.

Solution 2:

After some time I managed to recreate the animation by using the underlying functions directly and not using the animation wrapper:

import sys
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.patches import Circle
from matplotlib import animation
from time import sleep

classWindow(QtGui.QDialog): #or QtGui.QWidget ???def__init__(self):
        super(Window, self).__init__()
        self.fig = Figure(figsize=(5, 4), dpi=100)
        self.canvas = FigureCanvas(self.fig)
        self.ax = self.fig.add_subplot(111)  # create an axis
        self.ax.hold(False)  # discards the old graph
        self.ax.set_aspect('equal', 'box')
        self.circle = Circle((0,0), 1.0, animated=True)
        self.ax.add_artist(self.circle)
        self.ax.set_xlim([0, 10])
        self.ax.set_ylim([-2, 2])
        self.button = QtGui.QPushButton('Animate')
        self.button.clicked.connect(self.animate)

        # set the layout
        layout = QtGui.QVBoxLayout()
        layout.addWidget(self.canvas)
        layout.addWidget(self.button)
        self.setLayout(layout)
        self.canvas.draw()
        self.ax_background = self.canvas.copy_from_bbox(self.ax.bbox)

    defanimate(self):
        self.animate_loop(0)

    defanimate_loop(self,begin):
        for i inrange(begin,10):
            self.canvas.restore_region(self.ax_background)
            self.circle.center=(i,0)
            self.ax.draw_artist(self.circle)
            self.canvas.blit(self.ax.bbox)
            self.canvas.flush_events()
            sleep(0.1)

defmain():

    app = QtGui.QApplication(sys.argv)
    ex = Window()
    ex.show()
    sys.exit(app.exec_())

if __name__ == '__main__':
    main() 

Maybe this will be of use to you.

Post a Comment for "Getting Blitting To Work In Funcanimation Embedded In Pyqt4 Gui"