pythonpython-3.xmatplotlibscatter-plotmatplotlib-animation

How to use FuncAnimation to display one scatter marker per frame


I am trying to use the FuncAnimation of Matplotlib to animate the display of one dot per frame of animation.

# modules
#------------------------------------------------------------------------------
import numpy as np
import matplotlib.pyplot as py
from matplotlib import animation

py.close('all') # close all previous plots

# create a random line to plot
#------------------------------------------------------------------------------

x = np.random.rand(40)
y = np.random.rand(40)

py.figure(1)
py.scatter(x, y, s=60)
py.axis([0, 1, 0, 1])
py.show()

# animation of a scatter plot using x, y from above
#------------------------------------------------------------------------------

fig = py.figure(2)
ax = py.axes(xlim=(0, 1), ylim=(0, 1))
scat = ax.scatter([], [], s=60)

def init():
    scat.set_offsets([])
    return scat,

def animate(i):
    scat.set_offsets([x[:i], y[:i]])
    return scat,

anim = animation.FuncAnimation(fig, animate, init_func=init, frames=len(x)+1, 
                               interval=200, blit=False, repeat=False)

Unfortunately, the final animated plot is not the same as original plot. The animated plot also flashes several dots during each frame of animation. Any suggestions on how to correctly animate a scatter plot using the animation package?


Solution

  • The only problem with your example is how you fill the new coordinates in the animate function. set_offsets expects a Nx2 ndarray and you provide a tuple of two 1d arrays.

    So just use this:

    def animate(i):
        data = np.hstack((x[:i,np.newaxis], y[:i, np.newaxis]))
        scat.set_offsets(data)
        return scat,
    

    And to save the animation you might want to call:

    anim.save('animation.mp4')