matplotlib.animation#

Animazione #

Il modo più semplice per creare un'animazione dal vivo in Matplotlib è utilizzare una delle Animationclassi.

Diagramma di ereditarietà di matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation

Animation

Una classe base per le animazioni.

FuncAnimation

Crea un'animazione chiamando ripetutamente una funzione func .

ArtistAnimation

Animazione utilizzando un insieme fisso di Artistoggetti.

In entrambi i casi è fondamentale mantenere un riferimento all'oggetto istanza. L'animazione è avanzata da un timer (in genere dal framework della GUI host) a cui l' Animationoggetto contiene l'unico riferimento. Se non si tiene un riferimento Animationall'oggetto, esso (e quindi i timer) verrà sottoposto a raccolta dei rifiuti che interromperà l'animazione.

Per salvare un'animazione utilizzare Animation.save, Animation.to_html5_videoo Animation.to_jshtml.

Vedi Classi di supporto di seguito per i dettagli su quali formati di film sono supportati.

FuncAnimation#

Il funzionamento interno di FuncAnimationè più o meno:

for d in frames:
    artists = func(d, *fargs)
    fig.canvas.draw_idle()
    fig.canvas.start_event_loop(interval)

con dettagli per gestire il "blitting" (per migliorare notevolmente le prestazioni dal vivo), per non bloccare, non avviare/arrestare ripetutamente il ciclo di eventi della GUI, gestire le ripetizioni, più assi animati e salvare facilmente l'animazione in un file di filmato.

Il "Blitting" è una tecnica standard nella computer grafica. L'essenza generale è prendere una mappa di bit esistente (nel nostro caso una figura per lo più rasterizzata) e poi "blittare" un altro artista sopra. Pertanto, gestendo una bitmap "pulita" salvata, possiamo solo ridisegnare i pochi artisti che cambiano ad ogni fotogramma e possibilmente risparmiare notevoli quantità di tempo. Quando usiamo blitting (passando blit=True), il ciclo principale di FuncAnimationdiventa un po' più complicato:

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)

Questo ovviamente tralascia molti dettagli (come l'aggiornamento dello sfondo quando la figura viene ridimensionata o completamente ridisegnata). Tuttavia, questo esempio, si spera minimalista, dà un'idea di come init_func e funcsono usati all'interno FuncAnimatione della teoria di come funziona il "blitting".

La firma prevista su funced init_funcè molto semplice da tenere FuncAnimationfuori dalla tua logica di contabilità e trama, ma questo significa che gli oggetti richiamabili che passi devono sapere su quali artisti dovrebbero lavorare. Esistono diversi approcci per gestirlo, di varia complessità e incapsulamento. L'approccio più semplice, che funziona abbastanza bene nel caso di una sceneggiatura, è definire l'artista a livello globale e lasciare che Python risolva le cose. Per esempio

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()

Il secondo metodo consiste nell'usare functools.partialper 'legare' gli artisti alla funzione. Un terzo metodo consiste nell'usare le chiusure per costruire gli artisti e le funzioni richieste. Un quarto metodo consiste nel creare una classe.

Esempi #

ArtistAnimation#

Esempi #

Corsi di scrittura #

Diagramma di ereditarietà di matplotlib.animation.FFMpegFileWriter, matplotlib.animation.FFMpegWriter, matplotlib.animation.ImageMagickFileWriter, matplotlib.animation.ImageMagickWriter, matplotlib.animation.PillowWriter, matplotlib.animation.HTMLWriter

Gli scrittori forniti rientrano in alcune grandi categorie.

L'autore di Pillow si affida alla libreria Pillow per scrivere l'animazione, mantenendo tutti i dati in memoria.

PillowWriter

Il writer HTML genera animazioni basate su JavaScript.

HTMLWriter

Scrittore per filmati HTML basati su JavaScript.

I writer basati su pipe trasmettono i frame acquisiti tramite una pipe a un processo esterno. Le varianti basate su pipe tendono ad essere più performanti, ma potrebbero non funzionare su tutti i sistemi.

FFMpegWriter

Scrittore ffmpeg basato su pipe.

ImageMagickWriter

Gif animata basata su pipe.

I writer basati su file salvano file temporanei per ogni fotogramma che vengono uniti in un unico file alla fine. Sebbene più lenti, questi scrittori possono essere più facili da eseguire il debug.

FFMpegFileWriter

Scrittore ffmpeg basato su file.

ImageMagickFileWriter

Scrittore di gif animate basato su file.

Le classi writer forniscono un modo per acquisire frame sequenziali dallo stesso file Figure. Tutti forniscono tre metodi che devono essere chiamati in sequenza:

  • setupprepara lo scrittore (es. aprendo una pipa). Gli scrittori basati su pipe e file accettano argomenti diversi per setup().

  • grab_framepuò quindi essere chiamato tutte le volte che è necessario per acquisire un singolo fotogramma alla volta

  • finishfinalizza il filmato e scrive il file di output su disco.

Esempio:

moviewriter = MovieWriter(...)
moviewriter.setup(fig, 'my_movie.ext', dpi=100)
for j in range(n):
    update_figure(j)
    moviewriter.grab_frame()
moviewriter.finish()

Se si utilizzano direttamente le classi writer (non tramite Animation.save), si consiglia vivamente di utilizzare il savinggestore di contesto:

with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
    for j in range(n):
        update_figure(j)
        moviewriter.grab_frame()

per garantire che la configurazione e la pulizia vengano eseguite come necessario.

Esempi #

Classi di supporto #

Classi base di animazione #

Animation

Una classe base per le animazioni.

TimedAnimation

Animationsottoclasse per l'animazione basata sul tempo.

Registro degli scrittori n.

Viene fornito un registro a livello di modulo per eseguire il mapping tra il nome del writer e la classe per consentire il passaggio di una stringa Animation.saveanziché di un'istanza del writer.

MovieWriterRegistry

Registro delle classi di scrittori disponibili per nome leggibile dall'uomo.

Classi di base per scrittori #

Per ridurre le classi base di duplicazione del codice

AbstractMovieWriter

Classe base astratta per la scrittura di filmati, che fornisce un modo per catturare i fotogrammi chiamando grab_frame.

MovieWriter

Classe base per la scrittura di film.

FileMovieWriter

MovieWriterper la scrittura su singoli file e l'unione alla fine.

e mixin

FFMpegBase

Classe Mixin per l'output di FFMpeg.

ImageMagickBase

Classe Mixin per l'output di ImageMagick.

sono forniti.

Vedere il codice sorgente per come implementare facilmente nuove MovieWriterclassi.