Search code examples
pythonmatplotlibmatplotlib-animation

How to make the arrow blinking without changing its position using matplotlib animation?


I am new to python but finally seem to get the basic idea of how the animation works in matplotlib. However, I still can not figure out how to make the arrow to blink on one place pointing to the red circle (both circles remain static and not animated by any means). I thought that I could make it work just by duplicating the coordinates of the arrow thus making the number of frames to 2 with identic coordinates, but unfortunately it didn't work. I tried the examples shown here: Arrow animation in Python But ax.clear() doesn't suit my needs and ax.patches.remove(patch) for some reason is not working. The arrow remains static and get the "IndexError: list index out of range" error. I appreciate any advice!

Output: enter image description here

Example of my code:

import numpy as np
from matplotlib import pyplot as plt
from matplotlib.animation import FuncAnimation
from matplotlib import animation
import matplotlib.patches as patches

fig = plt.figure()
ax = fig.gca()

# Axes labels and title are established
ax = fig.gca()
ax.set_xlabel('x')
ax.set_ylabel('y')

ax.set_ylim(-20, 20)
ax.set_xlim(-20, 20)

# Drawing static circles:
circle1 = plt.Circle((10, 10), 3, color='red')
circle2 = plt.Circle((-10, -4), 2, color='blue')
ax.add_patch(circle1)
ax.add_patch(circle2)

# Coordinates of the arrow:
x = np.array([2, 2])
y = np.array([2, 2])
dx = x*2
dy = y*2

patch = patches.Arrow(x[0], y[0], dx[0], dy[0])


def init():
    ax.add_patch(patch)
    return patch,


def animate(i):
    global patch
    ax.patches.remove(patch)
    patch = patches.Arrow(x[i], y[i], dx[i], dy[i])
    ax.add_patch(patch)
    return patch,


anim = FuncAnimation(fig, animate, init_func=init,
                     frames=len(x), interval=200)

anim.save('222c.gif', writer='pillow')
plt.show()
plt.close()


Solution

  • To animate a blinking artist, the simplest solution is probably to turn the visibility of the artist on and off.

    enter image description here

    import numpy as np
    from matplotlib import pyplot as plt
    from matplotlib.animation import FuncAnimation
    
    import matplotlib.patches as patches
    
    fig, ax = plt.subplots()
    ax.set_ylim(-20, 20)
    ax.set_xlim(-20, 20)
    
    circle1 = plt.Circle((10, 10), 3, color='red')
    circle2 = plt.Circle((-10, -4), 2, color='blue')
    ax.add_patch(circle1)
    ax.add_patch(circle2)
    
    arrow = patches.Arrow(2, 2, 2, 2)
    ax.add_patch(arrow)
    
    def animate(ii):
        if ii % 2:
            arrow.set_visible(False)
        else:
            arrow.set_visible(True)
        return arrow,
    
    anim = FuncAnimation(fig, animate, frames=10, interval=200)
    anim.save('test.gif', writer='pillow')
    plt.show()