From: Arnd B. <arn...@we...> - 2004-12-17 18:37:20
|
Dear John, thank you very much for your helpful answer! On Thu, 16 Dec 2004, John Hunter wrote: > >>>>> "imaginee1" == imaginee1 <ima...@gm...> writes: [... snip frame rates ...] > 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 :-) That would be an interesting research project, but makes grant applications more complicated due to animal experiments ;-). The FPS numbers give us an estimate on the speed of the drawing process (see also below). > 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. We have a question here concerning the example you gave: is the whole screen updated with every `draw()`, including the axes and labels? If so there might be another (simpler) possibility by just updating the white plot-area. A problem might be the inward pointing tics. ((For the PlottingCanvas we solved this by having ticks pointing outward and using a separate frame for the inside of the plot)). > 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) This is indeed very nice and works (basically) the same for all backends. For this particular example we get: Double buffered Resizable xplt no no tkagg yes yes gtk yes (but: frameshift) no gtkagg no no wx no no wxagg no no Interestingly, in this dynamics example tkagg and gtk seem to have double buffering, i.e. at the end of the dynamics a damaged area gets repainted. With tkagg one can even resize the window at the end of the dynamics. (Actually, in the examples we posted double-buffering and resizing worked). Just a remark: For the gtk backend the double-buffer for the repaint is one frame behind. > 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. That could indeed give an substantial speed-up. > 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*. We will either need Tk or WX for our Windows using students. For Linux GTKAgg should do the job. > 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. I re-ran the tests on my laptop (PIII, 1.2 GHz) John laptop xplt 196 TkAgg 20 FPS 9 GTK 50 FPS 25 GTKAgg 36 FPS 18 WX 11 FPS 8 WXAgg 27 FPS 11 (Unfortunately, some of the students have even slower machines ;-(. To provide even more data (now a PIV, 2.8 GHz, debian sarge, but a different X driver, factor 3 slower for xplt!) 1000 pts 10000 pts 100000 pts xplt 330 FPS 159 FPS 43 FPS tkagg 23 FPS 16 FPS 4 FPS gtk 40 FPS 19 FPS 5 FPS gtkagg 31 FPS 24 FPS 4 FPS wx 12 FPS 3 FPS 0 FPS wxagg 24 FPS 16 FPS 4 FPS This shows the FPS when the number of points being plotted is increased. To answer your question from above: Something like 40 FPS for plotting 10000 points would be optimal. On slower machines (like my laptop) this might not be realizable. > 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. There is really no need to defend matplotlib (and we better don't post matplotlib's feature list here to emphasize the points we like!). Best, Nikolai and Arnd |