matplotlib.animation
#
Animation #
Le moyen le plus simple de créer une animation en direct dans Matplotlib consiste à utiliser l'une des
Animation
classes.
Une classe de base pour les animations. |
|
Crée une animation en appelant à plusieurs reprises une fonction func . |
|
Animation utilisant un ensemble fixe d' |
Dans les deux cas, il est essentiel de conserver une référence à l'objet instance. L'animation est avancée par une minuterie (généralement du framework GUI hôte) auquel l' Animation
objet détient la seule référence. Si vous ne détenez pas de référence à l' Animation
objet, celui-ci (et donc les minuteurs) sera ramassé, ce qui arrêtera l'animation.
Pour enregistrer une animation, utilisez Animation.save
, Animation.to_html5_video
ou Animation.to_jshtml
.
Voir Classes d'assistance ci-dessous pour plus de détails sur les formats de film pris en charge.
FuncAnimation
#
Le fonctionnement interne de FuncAnimation
est plus ou moins :
for d in frames:
artists = func(d, *fargs)
fig.canvas.draw_idle()
fig.canvas.start_event_loop(interval)
avec des détails pour gérer le "blitter" (pour améliorer considérablement les performances en direct), pour ne pas bloquer, ne pas démarrer/arrêter à plusieurs reprises la boucle d'événements de l'interface graphique, gérer les répétitions, plusieurs axes animés et enregistrer facilement l'animation dans un fichier vidéo.
Le 'Blitting' est une technique standard en infographie. L'essentiel est de prendre une image bitmap existante (dans notre cas, une figure principalement pixellisée), puis de "blit" un autre artiste par-dessus. Ainsi, en gérant un bitmap « propre » sauvegardé, on ne peut redessiner que les quelques artistes qui changent à chaque image et éventuellement gagner un temps considérable. Lorsque nous utilisons le blitting (en passant blit=True
), la boucle centrale de
FuncAnimation
devient un peu plus compliquée :
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)
Cela laisse bien sûr de côté de nombreux détails (comme la mise à jour de l'arrière-plan lorsque la figure est redimensionnée ou entièrement redessinée). Cependant, cet exemple, espérons-le, minimaliste, donne une idée de la façon dont init_func
et func
sont utilisés à l'intérieur de FuncAnimation
et de la théorie du fonctionnement du « blitting ».
La signature attendue sur func
et init_func
est très simple à garder FuncAnimation
en dehors de votre logique de comptabilité et de traçage, mais cela signifie que les objets appelables que vous transmettez doivent savoir sur quels artistes ils doivent travailler. Il existe plusieurs approches pour gérer cela, de complexité et d'encapsulation variables. L'approche la plus simple, qui fonctionne assez bien dans le cas d'un script, consiste à définir l'artiste dans une portée globale et à laisser Python régler les choses. Par exemple
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()
La deuxième méthode consiste à utiliser functools.partial
pour « lier » les artistes à la fonction. Une troisième méthode consiste à utiliser des fermetures pour constituer les artistes et les fonctions nécessaires. Une quatrième méthode consiste à créer une classe.
Exemples #
ArtistAnimation
#
Exemples #
Cours d'écrivain #
Les écrivains fournis se répartissent en quelques grandes catégories.
L'écrivain Pillow s'appuie sur la bibliothèque Pillow pour écrire l'animation, en gardant toutes les données en mémoire.
Le rédacteur HTML génère des animations basées sur JavaScript.
Écrivain pour les films HTML basés sur JavaScript. |
Les rédacteurs basés sur un canal diffusent les images capturées via un canal vers un processus externe. Les variantes basées sur des tuyaux ont tendance à être plus performantes, mais peuvent ne pas fonctionner sur tous les systèmes.
Écrivain ffmpeg basé sur un tube. |
|
Gif animé basé sur des tuyaux. |
Les écrivains basés sur des fichiers enregistrent des fichiers temporaires pour chaque image qui sont assemblés en un seul fichier à la fin. Bien que plus lents, ces écrivains peuvent être plus faciles à déboguer.
Écrivain ffmpeg basé sur des fichiers. |
|
Éditeur de gifs animés basé sur des fichiers. |
Les classes d'écriture fournissent un moyen de récupérer des images séquentielles à partir du même fichier Figure
. Ils fournissent tous trois méthodes qui doivent être appelées dans l'ordre :
setup
prépare l'écrivain (par exemple ouvrir une pipe). Les rédacteurs basés sur des tubes et basés sur des fichiers prennent des arguments différents poursetup()
.grab_frame
peut ensuite être appelé aussi souvent que nécessaire pour capturer une seule image à la foisfinish
finalise le film et écrit le fichier de sortie sur le disque.
Exemple:
moviewriter = MovieWriter(...)
moviewriter.setup(fig, 'my_movie.ext', dpi=100)
for j in range(n):
update_figure(j)
moviewriter.grab_frame()
moviewriter.finish()
Si vous utilisez les classes d'écriture directement (et non via Animation.save
), il est fortement recommandé d'utiliser le saving
gestionnaire de contexte :
with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
for j in range(n):
update_figure(j)
moviewriter.grab_frame()
pour s'assurer que la configuration et le nettoyage sont effectués selon les besoins.
Exemples #
Classes d'aide #
Classes de base d'animation #
Une classe de base pour les animations. |
|
|
Numéro de registre de l'écrivain
Un registre au niveau du module est fourni pour établir une correspondance entre le nom de l'écrivain et la classe afin de permettre à une chaîne d'être transmise à la
Animation.save
place d'une instance d'écrivain.
Registre des classes d'écrivains disponibles par nom lisible par l'homme. |
Classes de base de l'écrivain #
Pour réduire les classes de base de duplication de code
Classe de base abstraite pour écrire des films, fournissant un moyen de saisir des images en appelant |
|
Classe de base pour écrire des films. |
|
|
et mixins
Classe Mixin pour la sortie FFMpeg. |
|
Classe Mixin pour la sortie ImageMagick. |
sont prévus.
Voir le code source pour savoir comment implémenter facilement de nouvelles MovieWriter
classes.