如何多次使用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() 

但它绘制所有阵列一下子,有一些怪异的闪烁。

+0

动画的目的究竟是什么?也许你可以一步一步解释应该发生什么? – ImportanceOfBeingErnest

+0

@ImportanceOfBeingErnest我不知道我怎么能更清楚地解释它,但我会尝试: 我有一个numpy数组列表(这个列表在我发布的代码中称为mylines)。每个数组(在mylines列表中)都包含我想绘制的点的坐标......每个数组中有不同数量的点。我想遍历列表并设置动画,绘制每个数组中的点(每个帧为图添加一个新点)。 – vegzh

+0

@ImportanceOfBeingErnest当我尝试在问题中键入的代码时,它只动画第一个数组在mylines列表中的绘图,然后它就停止。我尝试使用断点调试代码,并且它成功通过for循环...即使FuncAnimation和plt.show()在每次循环时都被调用,它也不会为下一个数组播放动画。 – vegzh

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