imaginee1> Hi, we are trying to change from scipy.xplt to
imaginee1> matplotlib and need advice on dynamic plots. With the
imaginee1> examples at the end of this e-mail we get the following
imaginee1> frame rates (PIV, 2.8 GHz, debian sarge, python 2.3,
imaginee1> matplotlib 0.64)
imaginee1> FPS xplt 1000 (mov_sin_xplt.py) TkAgg 20
imaginee1> (mov_sin_mpl_tkagg.py) TkAgg2 5 (mov_sin_mpl_tkagg2.py)
imaginee1> gtk 60 (mov_sin_mpl_gtk.py) gtkAgg 37
imaginee1> (mov_sin_mpl_gtk.py)
1000 frames per second?? A typical top of the line monitor refreshes
at 75-100 FPS. How can you get 1000 frames per second? I'll humbly
suggest that you're not accurately measuring the true refresh rate of
xplt, while graciously acknowledging that xplt is much faster than
matplotlib.
Also, what refresh rate do you really need? DVD refreshes at 30FPS
and monitors typically around 75FPS. I suspect Andrew can tell us the
limits of the human visual system in terms of the maximal refresh rate
that is perceptible. I'm assuming you want to display these
animations to humans and not flies, which of course would be a
different story
I certainly agree that there are things matplotlib can, should and
will do to make this process faster. The first problem is that the
entire figure is updated with every frame. It would be much more
efficient in animated mode to designate certain elements only for
update. These elements could store the background image of their
bounding box, and on each update erase themselves (restore the
background) and redraw themselves with the new data. By limiting
redraws to only sections of the canvas, and only certain plot
elements, we should be able to get at least a 2x speedup, I'm
guessing.
imaginee1> More generally, our impression is that with matplotlib
imaginee1> the code tends to be more complicated (timers, classes
imaginee1> etc.) than the scipy.xplt version. Maybe there are
imaginee1> better ways to achieve what we want (but we haven't
imaginee1> found them yet ;-).
All this complication arises in attempting to deal with the mainloop.
You should be able to skip all this cruft, as you did for your tkagg
example, by running in interactive mode
import matplotlib
matplotlib.use('GTKAgg')
matplotlib.interactive(True)
from matplotlib.matlab import *
import time
x = arange(0,2*pi,0.01) # x-array
axis([0.0,2*pi,-1.0,1.0]) # setup axis
tstart = time.time()
line, = plot(x,sin(x))
for i in arange(1,200):
line.set_ydata(sin(x+i/10.0))
draw()
print 'FPS:' , 200/(time.time()-tstart)
Basically what matplotlib needs is a method like
for i in arange(1,200):
line.set_ydata(sin(x+i/10.0))
fig.update(line)
in place of the call to draw which redraws the entire figure.
imaginee1> We also have a wx version, but the code is really
imaginee1> complicated (any pointers on how to code our example
imaginee1> most simply with the wx backend
imaginee1> would be also very much appreciated).
Well, you'd have to post your code, but the interactive trick above
works for WX and WXAgg as well. But I doubt you'll beat GTK/GTKAgg
performance wise with WX*. With the example above, I get
TkAgg 20 FPS
GTK 50 FPS
GTKAgg 36 FPS
GTKCairo 15 FPS
WX 11 FPS
WXAgg 27 FPS
The performance problem with Tk animation is well known and w/o
resorting to platform dependent extension code, we don't have a good
way to solve it.
Note in matplotlib's defense, the fact that I can run the same
animated code across platforms and 4 GUIs (FLTK not profiled here) w/o
changing a single line of code says something about why it's slower
that xplt, which targets a single windowing system and thus can make
low level calls.
JDH