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