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