New/Fixed Simple Animation Example

I don’t know who I should notify about this, but I’ve found a fix for simple animation. If one uses the code found here: http://matplotlib.sourceforge.net/examples/animation/simple_anim_gtk.html it works okay, but if you try to move the window it freezes, and you can’t use anything on the toolbar. Really annoying, and why not quite a bug, its definitely undesirable behavior. So I’ve found a very simple fix that leaves the gui reasonably interactive and the window is freely movable. It centers around using a python generator and the yield statement. Calling “yield some_variable” in a function causes execution to stop at that point until the generator’s next() method is called, this
allows us to “pause” the execution of the animate() function and return control the gui thread. As it currently stands, once animate() is called it executes until completion, never allowing gui events to be handled, hence the freezing. The solution is changing too lines of code, note that this is for the GTK example but the same principle should be applicable to the other backends. Note that there are extra explanatory comments that could be removed when posting the actual example.

– Nathaniel

“”"
A simple example of an animated plot using a gtk backend
“”"
import time
import numpy as np
import matplotlib
matplotlib.use(‘GTKAgg’) # do this before importing pylab

import matplotlib.pyplot as plt

fig = plt.figure()

ax = fig.add_subplot(111)

def animate():
tstart =
time.time() # for profiling
x = np.arange(0, 2*np.pi, 0.01) # x-array
line, = ax.plot(x, np.sin(x))

for i in np.arange(1,200):
    line.set_ydata(np.sin(x+i/10.0))  # update the data
    fig.canvas.draw()                 # redraw the canvas

    # Here is generator magic that stops execution of animate() till the generators next() method is called
     yield True                       

continue animating

print 'FPS:' , 200/(time.time()-tstart)
raise SystemExit

import gobject
print ‘adding idle’

This is some lambda and python magic:

Python only evaluates defaults for arguments once,

so the first call to this lambda function sets iter to the generator made (automagically) from the animate() function.

Each subsequent call to the lambda function calls iter.next() which restarts(unpauses) execution of the animate() function,

until it yeilds again, at which point control goes back to the gui

These calls are done when the gui is idle, hence why we are registering an idle callback,

gobject.idle_add(lambda iter=animate(): iter.next())

print ‘showing’
plt.show()