0

I am trying to figure out how to embed a Matplotlib animation (using funcAnimation) within a PyQT GUI. There is surprisingly little that I could find on the web...this link was basically it, and it was difficult to follow:

Can I use Animation with Matplotlib widget for pyqt4?

The following code is a very simple animation using Matplotlib. It is just a circle moving across the screen, and it works fine:

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

The following is my attempt at embedding this animation within a PyQT GUI. (I believe I have prevented the reference to the animation object from being garbage collected by calling it self.anim):

import sys
from PyQt4 import QtGui, QtCore
from matplotlib.backends.backend_qt4agg import FigureCanvasQTAgg as FigureCanvas
import matplotlib.pyplot as plt
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 = plt.figure()
        self.canvas = FigureCanvas(self.fig)
        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.ax = self.fig.add_subplot(111)  # create an axis
        self.ax.hold(False)  # discards the old graph
        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.anim = animation.FuncAnimation(self.fig,self.animate_loop,frames=10,interval=100,repeat=False,blit=False)
        plt.show()

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

w = Window()
w.show()

Running this code brings up the GUI, but when I click the "Animate" button, nothing happens at all. There is not even an error message given in the console. Any insight would be much appreciated!

Community
  • 1
  • 1
dyson
  • 93
  • 8
  • You have to keep a reference to the `anim` object. – tacaswell Mar 23 '16 at 02:01
  • Thanks. That makes sense. I think I did that by modifying my code to call the reference self.anim...that should work, right? This doesn't solve the overall problem, though, because now nothing comes up at all when I press "Animate"--not even the first frame. – dyson Mar 23 '16 at 12:21
  • get rid of the `plt.show()` and see http://matplotlib.org/examples/user_interfaces/embedding_in_qt4.html Do not use `pyplot` if you intend to embed matplotlib qt your own application. – tacaswell Mar 23 '16 at 12:38
  • Thank you very much for the tip. My code now works. I replaced `self.fig = plt.figure()` with `self.fig = Figure(figsize=(5,4),dpi=100)` (which required `from matplotlib.figure import Figure`), and then I replaced `plt.show()` with `self.canvas.draw()`. (I cannot get the blitting to work, but that is a question for another post.) Thanks again! – dyson Mar 24 '16 at 01:23

0 Answers0