如何加快chaco图像情节

时间:2015-09-24 21:23:03

标签: python enthought chaco

我正在尝试使用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 个答案:

答案 0 :(得分:0)

这只是一个想法,但是最初将每个图像添加到您的ArrayPlotData中可以解决您的问题吗?然后你不是在动画的每一步添加一个新图像,只是在下一个系列中调用img_plot()。例如,如果您的图像存储在名为images [nt,nx,ny]的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())

这会对瓶颈有帮助吗?

答案 1 :(得分:0)

以下是我如何使用计时器在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()

我得到这样的东西:

Chaco demo