matplotlib.animation
#
Animación #
La forma más fácil de hacer una animación en vivo en Matplotlib es usar una de las
Animation
clases.
![Diagrama de herencia de matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation](/stable/_images/inheritance-affbd99b9440798c97774c4210e98ac086de4791.png)
Una clase base para animaciones. |
|
Realiza una animación llamando repetidamente a una función func . |
|
Animación utilizando un conjunto fijo de |
En ambos casos, es fundamental mantener una referencia al objeto de instancia. La animación es avanzada por un temporizador (típicamente desde el marco de la GUI del host) al que el Animation
objeto tiene la única referencia. Si no tiene una referencia al Animation
objeto, este (y por lo tanto los temporizadores) se recolectará como basura, lo que detendrá la animación.
Para guardar una animación, use Animation.save
, Animation.to_html5_video
o Animation.to_jshtml
.
Consulte Clases auxiliares a continuación para obtener detalles sobre qué formatos de película son compatibles.
FuncAnimation
#
El funcionamiento interno de FuncAnimation
es más o menos:
for d in frames:
artists = func(d, *fargs)
fig.canvas.draw_idle()
fig.canvas.start_event_loop(interval)
con detalles para manejar 'blitting' (para mejorar dramáticamente el rendimiento en vivo), para no bloquear, no iniciar / detener repetidamente el ciclo de eventos GUI, manejar repeticiones, múltiples ejes animados y guardar fácilmente la animación en un archivo de película.
'Blitting' es una técnica estándar en gráficos por computadora. La esencia general es tomar un mapa de bits existente (en nuestro caso, una figura en su mayoría rasterizada) y luego 'blit' a un artista más en la parte superior. Por lo tanto, al administrar un mapa de bits "limpio" guardado, solo podemos volver a dibujar los pocos artistas que cambian en cada cuadro y posiblemente ahorrar una cantidad significativa de tiempo. Cuando usamos blitting (pasando blit=True
), el ciclo central de
FuncAnimation
se vuelve un poco más complicado:
ax = fig.gca()
def update_blit(artists):
fig.canvas.restore_region(bg_cache)
for a in artists:
a.axes.draw_artist(a)
ax.figure.canvas.blit(ax.bbox)
artists = init_func()
for a in artists:
a.set_animated(True)
fig.canvas.draw()
bg_cache = fig.canvas.copy_from_bbox(ax.bbox)
for f in frames:
artists = func(f, *fargs)
update_blit(artists)
fig.canvas.start_event_loop(interval)
Por supuesto, esto deja fuera muchos detalles (como actualizar el fondo cuando la figura cambia de tamaño o se vuelve a dibujar por completo). Sin embargo, con suerte, este ejemplo minimalista da una idea de cómo init_func
y func
se usan dentro de FuncAnimation
la teoría de cómo funciona el 'blitting'.
La firma esperada en func
y init_func
es muy fácil de mantener FuncAnimation
fuera de su contabilidad y lógica de trazado, pero esto significa que los objetos invocables que pasa deben saber en qué artistas deberían estar trabajando. Hay varios enfoques para manejar esto, de diversa complejidad y encapsulación. El enfoque más simple, que funciona bastante bien en el caso de un guión, es definir al artista en un ámbito global y dejar que Python resuelva las cosas. Por ejemplo
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
fig, ax = plt.subplots()
xdata, ydata = [], []
ln, = ax.plot([], [], 'ro')
def init():
ax.set_xlim(0, 2*np.pi)
ax.set_ylim(-1, 1)
return ln,
def update(frame):
xdata.append(frame)
ydata.append(np.sin(frame))
ln.set_data(xdata, ydata)
return ln,
ani = FuncAnimation(fig, update, frames=np.linspace(0, 2*np.pi, 128),
init_func=init, blit=True)
plt.show()
El segundo método es utilizar functools.partial
para 'vincular' a los artistas a funcionar. Un tercer método es usar cierres para construir los artistas y funciones requeridos. Un cuarto método es crear una clase.
Ejemplos #
ArtistAnimation
#
Ejemplos #
Clases de escritor #
![Diagrama de herencia de matplotlib.animation.FFMpegFileWriter, matplotlib.animation.FFMpegWriter, matplotlib.animation.ImageMagickFileWriter, matplotlib.animation.ImageMagickWriter, matplotlib.animation.PillowWriter, matplotlib.animation.HTMLWriter](/stable/_images/inheritance-3dcd8c50b7666ebad3cfd5a1e11c2a1c646be52e.png)
Los escritores proporcionados se dividen en unas pocas categorías amplias.
El escritor de Pillow se basa en la biblioteca de Pillow para escribir la animación, manteniendo todos los datos en la memoria.
El escritor HTML genera animaciones basadas en JavaScript.
Escritor de películas HTML basadas en JavaScript. |
Los escritores basados en tuberías transmiten los fotogramas capturados a través de una tubería a un proceso externo. Las variantes basadas en tuberías tienden a tener un mayor rendimiento, pero es posible que no funcionen en todos los sistemas.
Escritor ffmpeg basado en tuberías. |
|
Gif animado basado en tuberías. |
Los escritores basados en archivos guardan archivos temporales para cada cuadro que se unen en un solo archivo al final. Aunque más lentos, estos escritores pueden ser más fáciles de depurar.
Escritor ffmpeg basado en archivos. |
|
Escritor de gifs animados basados en archivos. |
Las clases de escritor proporcionan una forma de obtener fotogramas secuenciales del mismo archivo Figure
. Todos proporcionan tres métodos que deben llamarse en secuencia:
setup
prepara al escritor (por ejemplo, abriendo una tubería). Los escritores basados en tuberías y en archivos toman diferentes argumentos parasetup()
.grab_frame
luego se puede llamar tantas veces como sea necesario para capturar un solo cuadro a la vezfinish
finaliza la película y escribe el archivo de salida en el disco.
Ejemplo:
moviewriter = MovieWriter(...)
moviewriter.setup(fig, 'my_movie.ext', dpi=100)
for j in range(n):
update_figure(j)
moviewriter.grab_frame()
moviewriter.finish()
Si usa las clases de escritor directamente (no a través Animation.save
de), se recomienda enfáticamente usar el saving
administrador de contexto:
with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
for j in range(n):
update_figure(j)
moviewriter.grab_frame()
para garantizar que la configuración y la limpieza se realicen según sea necesario.
Ejemplos #
Clases auxiliares #
Clases base de animación #
Una clase base para animaciones. |
|
|
Número de registro del escritor
Se proporciona un registro a nivel de módulo para mapear entre el nombre del escritor y la clase para permitir que se pase una cadena en
Animation.save
lugar de una instancia de escritor.
Registro de clases de escritor disponibles por nombre legible por humanos. |
Clases base de escritor #
Para reducir las clases base de duplicación de código
Clase base abstracta para escribir películas, que proporciona una forma de capturar fotogramas llamando a |
|
Clase base para escribir películas. |
|
|
y mezclas
Clase de mezcla para salida FFMpeg. |
|
Clase de mezcla para la salida de ImageMagick. |
están provistos.
Consulte el código fuente para saber cómo implementar fácilmente nuevas MovieWriter
clases.