2015-09-24 5 views
2

Я пытаюсь анимировать кучу 2D-изображений с chaco, но, к сожалению, это не так быстро, как мое приложение нуждается в нем. На данный момент я строю Чако Plot и используя img_plot, например .:Как ускорить графику изображения chaco

pd = ArrayPlotData() 
pd.set_data("imagedata", myarray) 
plot = Plot(pd) 
plot.img_plot("imagedata", interpolation="nearest") 

И чтобы обновить изображение, я использую следующее:

pd.set_data("imagedata", my_new_array) 

Это работает, но не достаточно быстро. Есть ли способ ускорить его? Любая функция нижнего уровня, которая позволяет быстрее обновлять изображение?

+0

У вас есть образы уже приобретенные или вы отображая при приобретении? –

+0

@ J.Corson Изображения уже находятся в трехмерном массиве, хранящемся в памяти (nt, nx, ny). Единственным узким местом является обновление сюжета. – tiago

+0

Если массив уже в памяти, вы можете просто «set_data» на другом фрагменте? Вы хотите быть осторожным, что вы не произвольно делаете копии массива. –

ответ

0

Это всего лишь мысль, но добавление каждого изображения изначально в вашу ArrayPlotData решит вашу проблему? Затем вы не добавляете новое изображение на каждом этапе анимации и просто вызываете img_plot() в следующей серии. Например, если ваши изображения хранятся в Numpy массиве называется изображений [нт, пх, пу]:

pd = ArrayPlotData() 
for index in range(images.shape[0]): #Assuming you want to iterate over nt 
    pd.set_data('', images[index,:,:], generate_name = True) 
plot = Plot(pd) 

Это автоматически называет каждый образ «Series1», «Series2» и т.д. Тогда вы можете позвонить:

plot.img_plot('series1', interpolation = 'nearest') #or 'series2' etc. 

для каждого изображения в вашей анимации без необходимости вызова set_data().

Вы можете получить отсортированный список ваших имен изображений [ 'Series1, „Series2“, ...] перебрать с помощью:

from natsort import natsorted #sort using natural sorting 
names = natsorted(pd.list_data()) 

Поможет с узким местом?

+0

-1. Наконец-то настало время для реализации вашего предложения. К сожалению, он в 20 раз медленнее моего первоначального подхода. Я не понимаю, почему делать img_plot с нуля каждый раз быстрее, чем просто обновлять данные. Испытания в реальном мире, похоже, согласны. – tiago

0

Вот пример того, как я делаю анимацию в Чако, используя таймер. Обычно трюк (как сказал J Corson) заключается в том, чтобы загрузить ваши данные в массив, а затем просто использовать индекс для принятия последовательных фрагментов массива.

from chaco.api import ArrayPlotData, Plot 
from enable.api import ComponentEditor 
import numpy as np 
from pyface.timer.api import Timer 
from traits.api import Array, Bool, Event, HasTraits, Instance, Int 
from traitsui.api import ButtonEditor, Item, View 


class AnimationDemo(HasTraits): 
    plot = Instance(Plot) 
    x = Array 
    y = Array 
    run = Bool(False) 
    go = Event 
    idx = Int 

    def _x_default(self): 
     x = np.linspace(-np.pi, np.pi, 100) 
     return x 

    def _y_default(self): 
     phi = np.linspace(0, 2 * np.pi, 360) 
     y = np.sin(self.x[:, np.newaxis] + phi[np.newaxis, :]) - \ 
      0.1 * np.sin(13 * self.x[:, np.newaxis] - 7 * phi[np.newaxis, :]) 
     return y 

    def _plot_default(self): 
     plot_data = ArrayPlotData(y=self.y[:, 0], x=self.x) 
     plot = Plot(plot_data) 
     plot.plot(('x', 'y')) 
     return plot 

    def _go_fired(self): 
     if not self.run: 
      self.run = True 
     else: 
      self.run = False 

    def _run_changed(self): 
     if self.run: 
      self.timer.Start() 
     else: 
      self.timer.Stop() 

    def _run_default(self): 
     self.timer = Timer(5, self._timer_tick) 
     return False 

    def _timer_tick(self): 
     if not self.run: 
      raise StopIteration 
     else: 
      if self.idx >= 360: 
       self.idx = 0 
      self.plot.data.set_data('y', self.y[:, self.idx]) 
      self.idx += 1 

    traits_view = View(
     Item('plot', editor=ComponentEditor(), show_label=False), 
     Item('go', editor=ButtonEditor(label="Start/Stop"), show_label=False), 
    ) 


if __name__ == "__main__": 
    ad = AnimationDemo() 
    ad.edit_traits() 

я получаю что-то вроде этого:

Chaco demo

+0

Благодарим вас за полный пример. Однако в вашем случае используется то же, что я использовал ('set_data'), поэтому он не меняет вещи для меня. – tiago

Смежные вопросы