matplotlib:我如何 "predraw" 动画?

matplotlib: how can I "predraw" an animation?

目前,我的自定义动画 class 的 _draw_frame 函数执行此操作:

  1. 获取时间步的线数据n
  2. 使用 set_data 更新轴中每条感兴趣线的数据(为了举例说明 (ax_line1.set_data(datax, datay,其中 ax_line1, = ax.plot(...))
  3. 列出更新的每一行,并将 self._drawn_artists 设置为该列表(因此在示例中,如果有两条感兴趣的行,那么我们更新它们 self._drawn_artists = [ax_line1, ax_line2]

有没有办法在 _draw_frame 被调用之前设置多个线条艺术家的数据?然后,_draw_frame 所要做的就是获取预绘制的线条,并用它更新绘制的艺术家列表。

这意味着我并行设置艺术家数据,如果我已经有了数据,从而更快地制作动画?我尝试对艺术家进行 copy.deepcopy,但出现错误提示我不能这样做(TransformationNode 必须被冻结)。我还有哪些其他选择?

如果你想并行设置数据,我认为你最好的选择是通过多次调用构造函数来创建你需要的所有线对象。然后您可以遍历它们并根据需要设置数据。如果您的许多行应该具有相同的共享属性,您可以使用 update_from method of matplotlib artists. You could freeze 一些行对象来实现此目的以允许复制它们,但是您将无法更改数据。

就是说,当您考虑到您还需要取消绘制线条时,我不确定这会为您节省多少时间。如果您有大量数据可以以非常并行的方式处理,那么这可能是值得的。

不过,如果你真的想加快速度,你可能应该使用 blitting。 blitting 背后的基本思想是这样的:

  • 首先绘制将出现在所有帧中的任何背景元素。
  • 动画中的所有其他元素都表示为某种可绘制对象(lines 很方便)
  • 对于每一帧,您都可以根据需要更新可绘制对象的任何属性。然后你 return 列出你更改属性的所有内容。
  • Matplotlib 的 FuncAnimation 函数以惊人的效率处理其余部分。

因为您的所有操作都涉及更新行,所以这是使用 blitting 的非常理想的场景。 Matplotlib 关于 blitting 的文档并不是非常清楚,所以,如果你想要更多细节,我写了 this tutorial,其中有示例代码等。