在for循环中使用不同参数多次运行FuncAnimation

时间:2017-12-06 04:14:54

标签: python animation matplotlib

我尝试使用不同的参数多次运行FuncAnimation,但每次完成模拟的第一次运行时,整个程序都会停止。它甚至不会运行我在初始运行FuncAnimation后调用的函数。

    T = [1,2,4,8]
    N = [20,40,60,80]
    for j in N:
        for k in T:
            anim = animation.FuncAnimation(fig,drawNext,interval = 10, frames = 300, repeat = False)
            plt.show()
            idealgas()
            count += 1

一旦运行完成,FuncAnimation会停止整个程序吗?我将repeat设置为false,因为我希望它在一定时间后退出,以便调用其他函数然后它将遍历forloop。但截至目前,它已经动画直到我指定的时间,然后没有其他事情发生。我在idealgas()函数中有一个print语句来检查它并且它从不打印所以我假设它永远不会到达那里。如果需要,我可以提供更多的背景,但是该程序的要点是找到具有不同数量的球和温度的盒子的理想气体常数。在此先感谢您的帮助,我是StackOverflow的新手,所以请放心使用。

1 个答案:

答案 0 :(得分:2)

动画结尾处的闭幕图

原则上你可以在循环中创建一个新的数字。然后关闭一个数字将允许程序继续并创建下一个数字并显示它。该图可以在动画结束时自动关闭。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

def createanimatedfig(omega):
    fig, ax = plt.subplots()
    ax.axis([0,2*np.pi,-1,1])
    ax.set_title(u"animated sin(${:g}\cdot t$)".format(omega))
    t = np.linspace(0,2*np.pi)
    x = np.sin(omega*t)
    line, = ax.plot([],[], lw=3)
    ani = FuncAnimation(fig,animate, len(t), repeat=False,
                        fargs=(t,x,line, len(t)), interval=20)
    plt.show()


def animate(i, t,x, line, maxsteps):
    line.set_data(t[:i],x[:i])
    if i >= maxsteps-1:
        plt.close(line.axes.figure)


omegas= [1,2,4,5]
for omega in omegas:
    createanimatedfig(omega)

请注意,使用TkAgg后端运行时,上述操作会产生错误。在这种情况下,你需要在动画真正停止后推迟关闭的数字。为此,可以使用计时器。

def animate(i, t,x, line, maxsteps):
    line.set_data(t[:i],x[:i])
    if i >= maxsteps-1:
        timer = line.axes.figure.canvas.new_timer(interval=10)
        timer.single_shot = True
        timer.add_callback(lambda : plt.close(line.axes.figure))
        timer.start()

在单个数字

内运行动画

或者,您可以使用单个图形一个接一个地显示所有动画。这需要控制何时停止动画,因此使用类来处理这些步骤是有用的。

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation

class Ani():
    def __init__(self,omegas, nsteps, line):
        self.nsteps = nsteps
        self.omegas = omegas
        self.line=line
        self.step = 0
        self.i = 0

    def getdata(self,j):
        t = np.arange(0,j)/float(self.nsteps)*2*np.pi
        x = np.sin(self.omegas[self.step]*t)
        return t,x

    def gen(self):
        for i in range(len(self.omegas)):
            tit = u"animated sin(${:g}\cdot t$)".format(self.omegas[self.step])
            self.line.axes.set_title(tit)
            for j in range(self.nsteps):
                yield j
            self.step += 1

    def animate(self,j):
        x,y = self.getdata(j)
        self.line.set_data(x,y)

fig, ax = plt.subplots()
ax.axis([0,2*np.pi,-1,1])
title = ax.set_title(u"")
line, = ax.plot([],[], lw=3)

omegas= [1,2,4,5]
a = Ani(omegas,50,line)
ani = FuncAnimation(fig,a.animate, a.gen, repeat=False, interval=60)
plt.show()