How can I speed up an animation?
I'm trying to create a Matplotlib animation of my paw data, where you can see the pressure distribution on the entire pressure plate over time (256x64 sensors for 250 frames).
I found a working example on Matplotlib's own site and managed to get it work开发者_如何学编程ing on my own data. However the 'animation' is awfully slow and I have no idea how to speed it up.
Here's an example of a gif Joe Kington made in another answer, which is about the speed with which it gets displayed. Considering the measurements are done at 125 Hz, this makes the measurements look awfully slow. If it ran at 30-60 fps, it could be run in 4 or 8 seconds rather than the current 20+.
I don't mind using whatever tool I need to get the job done, as long as there's some good documentation to figure out how to do it.
So my question is: how can I speed up these animations?
I've implemented Ignacio's suggestion to put in t.Start(1), however it only runs 'decently' when the Figure is this large:
class PlotFigure(Frame):
""" This class draws a window and updates it with data from DataCollect
"""
def __init__(self):
Frame.__init__(self, None, -1, "Test embedded wxFigure")
#Varying the size of Figure has a big influence on the speed
self.fig = Figure((3,3), 75)
self.canvas = FigureCanvasWxAgg(self, -1, self.fig)
EVT_TIMER(self, TIMER_ID, self.onTimer)
def init_plot_data(self):
self.datagen = DataCollect(array3d)
self.axes = self.fig.add_subplot(111)
self.axes.imshow(self.datagen.next().T)
def onTimer(self, evt):
self.data = self.datagen.next()
self.axes.imshow(self.datagen.next().T)
self.canvas.draw()
When I resize the window during the animation, it immediately slows down to a crawl. Which makes me suspect the delay isn't the only cause of the slow down. So any other suggestions? In case you're curious, here's a link to one of the ASCII files.
I found Joe Kington's answer that mentioned using Glumpy instead. At first I couldn't get it to work on my own data, but with some help on chat we managed to figure out how to adapt one of the Matplotlib examples that come with Glumpy to work on my data.
import numpy, glumpy
from glumpy.pylab import *
window = glumpy.Window(256,64)
Z = data.astype(numpy.float32)
t0, frames, t = 0,0,0
fig = plt.figure(figsize=(7,7))
ax = plt.subplot(111)
ax = imshow(Z[:,:,0], origin='lower', interpolation='bilinear')
show()
window = glumpy.active_window()
@window.event
def on_idle(dt):
global Z, t0, frames, t
t += dt
frames = frames + 1
if frames > 248:
fps = float(frames)/(t-t0)
print 'FPS: %.2f (%d frames in %.2f seconds)' % (fps, frames, t-t0)
frames,t0 = 0, t
for image, axis, alpha in items:
image.data[...] = Z[:,:,frames]
image.update()
window.draw()
window.mainloop()
The end result can be seen here, it doesn't matter how large I make the window, it will run at a very steady 58+ fps. So I must say, I'm very pleased with the end result!
The value passed to wx.Timer.Start()
is the trigger rate in milliseconds. Pass a smaller value.
Use a Profiler to find the root cause, frame skipping might be useful too as a last resort.
Or switch to an alternative solution like Double Buffering using Device Contexts or PyOpenGL...
精彩评论