2

我正在尝试使用 chaco 为一堆 2D 图像设置动画,但不幸的是它似乎没有我的应用程序需要的那么快。目前我正在构建一个 chacoPlot并使用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)

这行得通,但是不够快。有什么办法可以加快速度吗?任何允许更快更新图像的较低级别的功能?

4

2 回答 2

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

我得到这样的东西:

查科演示

于 2015-09-29T01:55:33.593 回答
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())

这对瓶颈有帮助吗?

于 2015-09-25T17:13:08.073 回答