Getting blitting to work in funcAnimation embedded in PyQT4 GUI

Viewed 1481

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 matplotlib.pyplot as plt
from matplotlib.patches import Circle
from matplotlib import animation

fig,ax = plt.subplots()
ax.set_aspect('equal','box')
circle = Circle((0,0), 1.0)
ax.add_artist(circle)
ax.set_xlim([0,10])
ax.set_ylim([-2,2])

def animate(i):
    circle.center=(i,0)
    return circle, 

anim = animation.FuncAnimation(fig,animate,frames=10,interval=100,repeat=False,blit=True)

plt.show()

I am able to accomplish this using the following code, but there is one hitch: I cannot get blitting to work.

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

class Window(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)
        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)

    def animate(self):
        self.anim = animation.FuncAnimation(self.fig,self.animate_loop,frames=10,interval=100,repeat=False,blit=False)
        self.canvas.draw()

    def animate_loop(self,i):
        self.circle.center=(i,0)
        return self.circle, 

def main():

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

if __name__ == '__main__':
    main()  

When I set blit=True, after pressing the Animate button I get the following error: a.figure.canvas.restore_region(bg_cache[a]) KeyError: matplotlib.axes._subplots.AxesSubplot object at 0x00000000095F1D30

In searching this error, I find many posts about how blitting does not work on Macs, but I am using Windows 7. I have tried replacing self.canvas.draw() with self.canvas.update(), but this does not work.

2 Answers
Related