I want to make a very simple animation of 3 frames:
- In the first frame there are only tree black circle,
- In the second the same black circles and an arrow above the last one,
- In the last there are 3 black circles and a green one to the right of the last one.
I am making the animation with the following code:
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib
def make_circles(s):
circles=[]
radius=0.45
pad=0.5-radius
for i,x in enumerate(s):
if x==0:
circles.append(plt.Circle((i radius pad, 0), radius, facecolor='white', edgecolor="black"))
elif x==1:
circles.append(plt.Circle((i radius pad, 0), radius, color='black'))
else:
circles.append(plt.Circle((i radius pad, 0), radius, color='green'))
return circles
if __name__=="__main__":
data=[[0,1,1,1,0],
[0,1,1,1,0],
[0,1,1,1,2]]
N=5
to_animate=[]
for i,x in enumerate(data):
c=make_circles(x)
if(i==1):
a=plt.Arrow(3.5,2,0,-1)
c.append(a)
to_animate.append(c)
fig, ax = plt.subplots()
ax.set_xlim(-0.5,N 0.5)
ax.set_ylim(-2,2)
def animate(i):
for cir in to_animate[i]:
ax.add_patch(cir)
ani=FuncAnimation(fig, animate, frames=3, repeat=False)
#ani.save('./animation.gif', writer='imagemagick', fps=1)
plt.show()
However at the moment at the second iteration I am drawing above the elements on the first iteration, and at the third above the second. This is made clear by the fact that the arrow does not disappear when the last circle is green.
How can I erase the patches belonging to the previous iteration before drawing the new one?
CodePudding user response:
At each new iteration, you could first
CodePudding user response:
At each iteration you are adding new patches. Instead, you should add all the elements of the plot at the beginning, and then control their visibility during the animation sequence. During the call to animate
you will can set the visibility of particular objects, and then return list of patches.
Here is an example that keeps the code relatively similarto its previous current form
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
import matplotlib
def make_circles(s):
circles = []
radius = 0.45
pad = 0.5 - radius
for i, x in enumerate(s):
circles.append(plt.Circle((i radius pad, 0), radius, facecolor='white', edgecolor="black"))
if x == 1:
circles.append(plt.Circle((i radius pad, 0), radius, color='black'))
elif x == 2:
circles.append(plt.Circle((i radius pad, 0), radius, color='green'))
return circles
to_animate = make_circles([0, 1, 1, 1, 2])
to_animate.append(plt.Arrow(3.5, 2, 0, -1))
hidden_at_start = [8, 9]
for ix in hidden_at_start:
to_animate[ix].set_visible(False)
fig, ax = plt.subplots()
for patch in to_animate:
ax.add_patch(patch)
ax.set_xlim(-0.5, N 0.5)
ax.set_ylim(-2, 2)
def animate(i):
if i == 0:
pass
elif i == 1:
to_animate[-1].set_visible(True)
else:
to_animate[-2].set_visible(True)
to_animate[-1].set_visible(False)
return to_animate,
ani = FuncAnimation(fig, animate, frames=3, repeat=False)
# ani.save('./animation.gif', writer='imagemagick', fps=1)
plt.show()