Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Matplotlib animation either freezes after a few frames or just doesn't work

I've been trying for hours to get this simple script working, but nothing I do seems to help. It's a slight modification of the most basic animated plot sample code from the Matplotlib website, that should just show a few frames of noise (I have the same issue with the unmodified code from their website BTW).

On my computer with the TkAgg backend I get about 20 frames (out of 60) before the plot window freezes. With Qt4Agg I just get a frozen, black window and no frames at all are plotted. I've tried multiple combinations of different NumPy, PyQt, Python and Matplotlib versions, but always get the same result.

Please let me know if this works for you or if anything looks wrong. I'm pretty sure this did work in the past, so I'm thinking it may be a Windows issue or something related to ion().

FYI I'm using Windows 7 (32 bit) and I've tested with Python 2.6/2.7, MPL 1.0.0/0.9.9.8, PyQt 4.6/4.7, Numpy 1.4/1.5b.

import matplotlib
matplotlib.use('TkAgg') # Qt4Agg gives an empty, black window
from pylab import *
import time

ion()
hold(False)

# create initial plot
z = zeros(10)
line, = plot(z)
ylim(-3, 3)

for i in range(60):
    print 'frame:', i

    d = randn(10)
    line.set_ydata(d)

    draw()
    time.sleep(10e-3)

This simpler version also freezes after the first couple frames:

from pylab import *

ion()
hold(False)

for i in range(40):
    plot(randn(10))
    draw()

show()

Thanks!

EDIT: These people seem to be having the same or a similar problem as me:

  • mail-archive.com/[email protected]/msg10844.html
  • stackoverflow.com/questions/2604119/matplotlib-pyplot-pylab-not-updating-figure-while-isinteractive-using-ipython
  • mail-archive.com/[email protected]/msg01283.html

Doesn't look like any of them were able to fix it either :(

like image 201
Roger Avatar asked Aug 09 '10 16:08

Roger


1 Answers

Typically, GUI frameworks need to 'own' the main loop of the program. Sitting in a tight loop with sleeps to delay iterations will usually 'break' GUI applications (your problem description is consistent with typical breakage along these lines). It's possible that the matplotlib devs have implemented some behind the scenes logic to pevent these lockups from happening for certain toolkits but restructuring your program slightly should eliminate any chance of mainloop ownership being the problem (which is very likely I think). The matplotlib animation wiki also suggests using native event loops for anything nontrivial (probably for this reason)

Rather than sitting in a loop with sleeps, I suggest that, instead, you use the GUI toolkit to schedule a function call after a certain delay.

def update_function():
    # do frame calculation here

refresh_timer = QtCore.QTimer()
QtCore.QObject.connect( refresh_timer, QtCore.SIGNAL('timeout()'), update_function )
refresh_timer.start( 1.0 / 30 ) # have update_function called at 30Hz

Looking at the matplotlib documentation suggests that it may be possible to use their API natively but I couldn't find any good examples using just a quick search.

like image 135
Rakis Avatar answered Sep 29 '22 06:09

Rakis