Running FuncAnimation multiple times with differen

2019-03-03 11:10发布

I'm trying to run FuncAnimation multiple times with different parameters but every time it gets through the first run of the simulation, the entire program stops. It won't even run the functions that I call after the initial run of 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

Does FuncAnimation stop the entire program once the run is through? I set repeat to false as I want it to quit after a certain amount of time so that the other functions will be called and then it will iterate through the forloop. But as of right now, it animates until the time I have specified and then nothing else happens. I have a print statement in the idealgas() function to check it and it never prints so I'm assuming it never gets there. I can provide more context if need be, but the jist of this program is finding the ideal gas constant of a box with a varying number of balls and temperature. Thanks in advance for the help, I'm new to StackOverflow so go easy on me.

1条回答
该账号已被封号
2楼-- · 2019-03-03 11:47

Closing figure at the end of animation

You could in principle create a new figure inside the loop. Then closing one figure will allow the program to continue and create the next figure and show it. The figure can be closed automatically at the end of the animation.

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)

Note that the above will produce an error when run with the TkAgg backend. In this case you need to postpone the figure closing to after the animation has truely stopped. To this end a timer may be used.

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

Run animations within single figure

Alternatively you may use a single figure to show all animations one after the other. This would require to have some control over when which animation stops and so the use of a class to handle the steps is useful.

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()
查看更多
登录 后发表回答