Как ускорить сюжет изображения chaco
Я пытаюсь анимировать кучу 2D-изображений с помощью chaco, но, к сожалению, это не так быстро, как нужно моему приложению. На данный момент я строю чако Plot
и используя img_plot
Например:
pd = ArrayPlotData()
pd.set_data("imagedata", myarray)
plot = Plot(pd)
plot.img_plot("imagedata", interpolation="nearest")
И чтобы обновить изображение, я использую следующее:
pd.set_data("imagedata", my_new_array)
Это работает, однако не достаточно быстро. Есть ли способ ускорить его? Любая функция более низкого уровня, которая позволяет быстрее обновлять изображение?
2 ответа
Это всего лишь мысль, но решит ли ваша проблема добавление каждого изображения в ArrayPlotData? Тогда вы не добавляете новое изображение на каждом этапе анимации, а просто вызываете img_plot() в следующей серии. Например, если ваши изображения хранятся в массиве numpy с именем images[nt, nx, ny]:
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())
Это поможет с узким местом?
Вот пример того, как я делаю анимацию в Chaco, используя таймер. Обычно хитрость (как сказал 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()
Я получаю что-то вроде этого: