Как я могу ускорить анимацию? - PullRequest
16 голосов
/ 15 февраля 2011

Я пытаюсь создать анимацию Matplotlib моих данных лапы, где вы можете увидеть распределение давления на всей пластине давления за время (256x64 датчиков для 250 кадров).

Я нашел рабочий пример на собственном сайте Matplotlib и смог заставить его работать на моих собственных данных. Однако «анимация» ужасно медленная, и я не знаю, как ее ускорить.

Вот пример изображения Джо Кингтона , сделанного в другом ответе , о скорости, с которой он отображается. Учитывая, что измерения выполняются при 125 Гц, это делает измерения очень медленными. Если бы он работал со скоростью 30-60 кадров в секунду, он мог бы быть запущен за 4 или 8 секунд вместо текущих 20+.

enter image description here enter image description here

Я не против использовать любой инструмент, который мне нужен для выполнения работы, если есть хорошая документация, чтобы выяснить, как это сделать.

Итак, мой вопрос: как я могу ускорить анимацию?

Я реализовал предложение Игнасио о включении t.Start (1), однако он работает «прилично» только при большом размере рисунка:

enter image description here

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()

Когда я изменяю размер окна во время анимации, оно сразу замедляется до сканирования. Что заставляет меня подозревать, что задержка - не единственная причина замедления. Итак, есть ли другие предложения? Если вам интересно, вот ссылка на один из файлов ASCII.

Ответы [ 3 ]

8 голосов
/ 29 марта 2011

Я нашел ответ Джо Кингтона, в котором упоминалось использование вместо него Glumpy . Сначала я не мог заставить его работать на моих собственных данных, но с некоторой помощью в чате нам удалось выяснить, как адаптировать один из примеров Matplotlib, который поставляется с Glumpy работать с моими данными.

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()

Конечный результат можно увидеть здесь, не имеет значения, насколько велико мое окно, оно будет работать с очень устойчивой скоростью 58+ кадров в секунду. Поэтому я должен сказать, что я очень доволен конечным результатом!

enter image description here

4 голосов
/ 15 февраля 2011

Значение, переданное wx.Timer.Start() - это частота срабатывания в миллисекундах.Передайте меньшее значение.

1 голос
/ 19 февраля 2011

Используйте Профилировщик, чтобы найти основную причину, пропуск кадров также может быть полезен в качестве крайней меры.

Или переключитесь на альтернативное решение, такое как Двойная буферизация с использованием контекста устройства или PyOpenGL ...

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...