如何多次使用FuncAnimation(按顺序,不是全部一起)?
问题描述:
是否有某种方法可以在同一代码中多次调用matplotlib.animation.FuncAnimation?我有一个numpy数组列表。每个数组都包含不同数量的坐标。我想遍历列表并设置动画,绘制每个数组中的点。如何多次使用FuncAnimation(按顺序,不是全部一起)?
有什么我可以做的,以实现这两种不同的情况: 1.保留上一帧的动画,并开始一个新的动画。 2.摆脱上一个动画的最后一帧,并开始一个新的动画,但在代码的开头保持相同的布局(包括背景图)。
当我尝试在下面的for循环中使用FuncAnimation时,只有第一个数组会变成动画。在每个数组之间,我还需要做其他一些事情,所以我不能摆脱for循环并将数组合并成动画。
import numpy as np
import matplotlib.animation as animation
import matplotlib.pyplot as plt
mylines = [np.array([[1,2], [3,4]]), np.array([[5,6], [7,8], [9,10]])]
fig, ax = plt.subplots()
ax.set_xlim([-10, 10])
ax.set_ylim([-10, 10])
# There's some code here to set the layout (some background plots etc)
# I omitted it in this question
def update_plot(i, data, myplot):
myplot.set_data(data[:i, 0], data[:i, 1])
return myplot,
myplot, = ax.plot([], [], '.', markersize=5)
for k in xrange(len(mylines)):
data = mylines[k]
numframes = data.shape[0]+1
delay = 500
ani = animation.FuncAnimation(fig, update_plot, frames=numframes,
fargs=(data, myplot), interval=delay,
blit=True, repeat=False)
plt.show()
# Do some more stuff in the for loop here, that's not related to
# animations but related to the current array
# Then I want to retain the last frame from the animation, and start a new
# animation on top of it. Also, what should I do if I want to erase the
# last frame instead (erase only the points plotted by the FuncAnimation,
# but keep the layout I set at the beginning)
*编辑的代码,因为它有一些语法错误
也试过以下this question's solution:
ani = []
for k in xrange(len(mylines)):
data = mylines[k]
numframes = data.shape[0]+1
delay = 100
ani.append(animation.FuncAnimation(fig, update_plot, frames=numframes,
fargs=(data, myplot), interval=delay,
blit=True, repeat=False))
plt.show()
但它绘制所有阵列一下子,有一些怪异的闪烁。
答
把FuncAnimation
想象成一个计时器。它只会以给定的参数以给定的速率调用提供给它的函数。您可以使用调用的用于管理动画流的函数,而不是使用两个定时器,而这两个定时器在每个定时器都要启动并完成时需要进行管理。
例如,您可以设置某物应该在动画过程中发生的一帧序号:
import numpy as np
import matplotlib.animation as animation
import matplotlib.pyplot as plt
mylines = [np.array([[1,2], [3,4]]), np.array([[5,6], [7,8], [9,10]])]
fig, ax = plt.subplots()
ax.set_xlim([-10, 10])
ax.set_ylim([-10, 10])
# There's some code here to set the layout (some background plots etc)
# I omitted it in this question
myplot, = ax.plot([], [], '.', markersize=5)
delay = 500
breaking = 1
def update_plot(i, data, myplot):
myplot.set_data(data[:i, 0], data[:i, 1])
if i == breaking:
# do some other stuff
print("breaking")
myplot.set_color("red")
return myplot,
data = np.append(mylines[0],mylines[1], axis=0)
ani = animation.FuncAnimation(fig, update_plot, frames=data.shape[0],
fargs=(data, myplot), interval=delay,
blit=True, repeat=False)
plt.show()
当然,这可以任意复杂。例如,请参阅此问题:Managing dynamic plotting in matplotlib Animation module,其中动画的方向在用户输入时反转。但是,它仍然使用一个单独的FuncAnimation
。
动画的目的究竟是什么?也许你可以一步一步解释应该发生什么? – ImportanceOfBeingErnest
@ImportanceOfBeingErnest我不知道我怎么能更清楚地解释它,但我会尝试: 我有一个numpy数组列表(这个列表在我发布的代码中称为mylines)。每个数组(在mylines列表中)都包含我想绘制的点的坐标......每个数组中有不同数量的点。我想遍历列表并设置动画,绘制每个数组中的点(每个帧为图添加一个新点)。 – vegzh
@ImportanceOfBeingErnest当我尝试在问题中键入的代码时,它只动画第一个数组在mylines列表中的绘图,然后它就停止。我尝试使用断点调试代码,并且它成功通过for循环...即使FuncAnimation和plt.show()在每次循环时都被调用,它也不会为下一个数组播放动画。 – vegzh