Home > other >  How to remove a list of patches?
How to remove a list of patches?

Time:07-22

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?

CodePudding user response:

At each new iteration, you could first enter image description here

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