Matplotlib puede crear animaciones actualizando una figura fotograma a fotograma. La clase FuncAnimation llama a una función en cada fotograma, en la que modificas los elementos del gráfico. El resultado se puede mostrar en un notebook o guardar como GIF o como vídeo.
FuncAnimation
El flujo de trabajo habitual es: crear la figura y los elementos que quieres animar, escribir una función que los actualice para un fotograma dado y pasarla a FuncAnimation junto con el número de fotogramas. interval establece el tiempo entre fotogramas en milisegundos.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = np.linspace(0, 10, 200)
fig, ax = plt.subplots(figsize = (4, 4))
line, = ax.plot(x, np.sin(x))
ax.set_ylim(-1.2, 1.2)
def update(frame):
line.set_ydata(np.sin(x + frame / 10))
return line,
ani = FuncAnimation(fig, update, frames = 63, interval = 40)
# plt.show()

En lugar de mover los datos puedes mostrarlos progresivamente, actualizando los valores de X e Y de la línea con set_data.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
x = np.linspace(0, 10, 100)
y = np.random.default_rng(1).normal(size = 100).cumsum()
fig, ax = plt.subplots(figsize = (4, 4))
line, = ax.plot([], [])
ax.set_xlim(0, 10)
ax.set_ylim(y.min() - 1, y.max() + 1)
def update(frame):
line.set_data(x[:frame], y[:frame])
return line,
ani = FuncAnimation(fig, update, frames = len(x) + 1, interval = 40)
# plt.show()

Los puntos de un gráfico de dispersión se actualizan con set_offsets, que recibe un array con las coordenadas X e Y.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
rng = np.random.default_rng(2)
points = rng.normal(size = (50, 2))
fig, ax = plt.subplots(figsize = (4, 4))
sc = ax.scatter(points[:, 0], points[:, 1])
ax.set_xlim(-4, 4)
ax.set_ylim(-4, 4)
def update(frame):
points[:] = points + rng.normal(0, 0.05, points.shape)
sc.set_offsets(points)
return sc,
ani = FuncAnimation(fig, update, frames = 60, interval = 50)
# plt.show()

En los gráficos de barras actualiza la altura de cada barra con set_height.
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
rng = np.random.default_rng(3)
data = rng.uniform(1, 10, (30, 5)).cumsum(axis = 0)
fig, ax = plt.subplots(figsize = (4, 4))
bars = ax.bar(["A", "B", "C", "D", "E"], data[0])
ax.set_ylim(0, data.max() * 1.05)
def update(frame):
for bar, height in zip(bars, data[frame]):
bar.set_height(height)
ax.set_title(f"Paso {frame + 1}")
return bars
ani = FuncAnimation(fig, update, frames = len(data), interval = 100)
# plt.show()

Guarda la animación con el método save. Los archivos GIF se crean con Pillow, que se instala junto con matplotlib, mientras que los vídeos MP4 necesitan tener FFmpeg instalado en tu sistema.
from matplotlib.animation import PillowWriter, FFMpegWriter
ani.save("animacion.gif", writer = PillowWriter(fps = 25))
ani.save("animacion.mp4", writer = FFMpegWriter(fps = 25))
En un notebook de Jupyter la animación no se muestra con plt.show(). En su lugar conviértela a HTML:
from IPython.display import HTML
HTML(ani.to_jshtml())
Guarda una referencia al objeto de la animación (ani = FuncAnimation(...)). Si el objeto se elimina, la animación se detiene. Para aprender a exportar gráficos estáticos consulta cómo guardar gráficos en matplotlib.
También te puede interesar