Search code examples
pythonmatplotlibmatplotlib-animation

How to remove a list of patches?


I want to make a very simple animation of 3 frames:

  1. In the first frame there are only tree black circle,
  2. In the second the same black circles and an arrow above the last one,
  3. 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. GIF representing it

How can I erase the patches belonging to the previous iteration before drawing the new one?


Solution

  • At each new iteration, you could first remove the patches added in the previous iteration:

    def animate(i):
        if i > 0:
            for cir in to_animate[i-1]:
                cir.remove()
        for cir in to_animate[i]:
            ax.add_patch(cir)
    

    enter image description here