matplotlib.animation#

Animación #

La forma más fácil de hacer una animación en vivo en Matplotlib es usar una de las Animationclases.

Diagrama de herencia de matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation

Animation

Una clase base para animaciones.

FuncAnimation

Realiza una animación llamando repetidamente a una función func .

ArtistAnimation

Animación utilizando un conjunto fijo de Artistobjetos.

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 Animationobjeto tiene la única referencia. Si no tiene una referencia al Animationobjeto, 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_videoo 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 FuncAnimationes 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 FuncAnimationse 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 funcse usan dentro de FuncAnimationla teoría de cómo funciona el 'blitting'.

La firma esperada en funcy init_funces muy fácil de mantener FuncAnimationfuera 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.partialpara '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

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.

PillowWriter

El escritor HTML genera animaciones basadas en JavaScript.

HTMLWriter

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.

FFMpegWriter

Escritor ffmpeg basado en tuberías.

ImageMagickWriter

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.

FFMpegFileWriter

Escritor ffmpeg basado en archivos.

ImageMagickFileWriter

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:

  • setupprepara al escritor (por ejemplo, abriendo una tubería). Los escritores basados ​​en tuberías y en archivos toman diferentes argumentos para setup().

  • grab_frameluego se puede llamar tantas veces como sea necesario para capturar un solo cuadro a la vez

  • finishfinaliza 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.savede), se recomienda enfáticamente usar el savingadministrador 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 #

Animation

Una clase base para animaciones.

TimedAnimation

Animationsubclase para animación basada en el tiempo.

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.savelugar de una instancia de escritor.

MovieWriterRegistry

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

AbstractMovieWriter

Clase base abstracta para escribir películas, que proporciona una forma de capturar fotogramas llamando a grab_frame.

MovieWriter

Clase base para escribir películas.

FileMovieWriter

MovieWriterpara escribir en archivos individuales y coser al final.

y mezclas

FFMpegBase

Clase de mezcla para salida FFMpeg.

ImageMagickBase

Clase de mezcla para la salida de ImageMagick.

están provistos.

Consulte el código fuente para saber cómo implementar fácilmente nuevas MovieWriterclases.