matplotlib.animation#

Animação #

A maneira mais fácil de fazer uma animação ao vivo no Matplotlib é usar uma das Animationclasses.

Diagrama de herança de matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation

Animation

Uma classe base para animações.

FuncAnimation

Faz uma animação chamando repetidamente uma função func .

ArtistAnimation

Animação usando um conjunto fixo de Artistobjetos.

Em ambos os casos, é fundamental manter uma referência ao objeto da instância. A animação é avançada por um cronômetro (normalmente da estrutura da GUI do host) ao qual o Animationobjeto contém a única referência. Se você não mantiver uma referência ao Animationobjeto, ele (e, portanto, os temporizadores) será coletado como lixo, o que interromperá a animação.

Para salvar uma animação, use Animation.save, Animation.to_html5_videoou Animation.to_jshtml.

Consulte as classes auxiliares abaixo para obter detalhes sobre quais formatos de filme são suportados.

FuncAnimation#

O funcionamento interno de FuncAnimationé mais ou menos:

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

com detalhes para lidar com 'blitting' (para melhorar drasticamente o desempenho ao vivo), não bloquear, não iniciar/parar repetidamente o loop de eventos da GUI, lidar com repetições, vários eixos animados e salvar facilmente a animação em um arquivo de filme.

'Blitting' é uma técnica padrão em computação gráfica. A essência geral é pegar um mapa de bits existente (no nosso caso, uma figura quase toda rasterizada) e então 'blit' mais um artista no topo. Assim, ao gerenciar um bitmap 'limpo' salvo, podemos apenas redesenhar os poucos artistas que estão mudando a cada quadro e possivelmente economizar uma quantidade significativa de tempo. Quando usamos blitting (passando blit=True), o loop principal de FuncAnimationfica um pouco mais 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)

É claro que isso está deixando de fora muitos detalhes (como atualizar o plano de fundo quando a figura é redimensionada ou totalmente redesenhada). No entanto, este exemplo esperançosamente minimalista dá uma noção de como init_func e funcsão usados ​​dentro de FuncAnimatione a teoria de como 'blitting' funciona.

A assinatura esperada em funce init_funcé muito simples de manter FuncAnimationfora de sua contabilidade e lógica de plotagem, mas isso significa que os objetos chamáveis ​​que você passa devem saber em quais artistas eles devem estar trabalhando. Existem várias abordagens para lidar com isso, de complexidade e encapsulamento variados. A abordagem mais simples, que funciona muito bem no caso de um script, é definir o artista em um escopo global e deixar que o Python resolva as coisas. Por exemplo

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

O segundo método é usar functools.partialpara 'vincular' os artistas à função. Um terceiro método é usar encerramentos para criar os artistas e funções necessários. Um quarto método é criar uma classe.

Exemplos #

ArtistAnimation#

Exemplos #

Aulas de Escritor #

Diagrama de herança de matplotlib.animation.FFMpegFileWriter, matplotlib.animation.FFMpegWriter, matplotlib.animation.ImageMagickFileWriter, matplotlib.animation.ImageMagickWriter, matplotlib.animation.PillowWriter, matplotlib.animation.HTMLWriter

Os escritores fornecidos se enquadram em algumas categorias amplas.

O Pillow Writer depende da biblioteca Pillow para escrever a animação, mantendo todos os dados na memória.

PillowWriter

O gravador de HTML gera animações baseadas em JavaScript.

HTMLWriter

Escritor de filmes HTML baseados em JavaScript.

Os gravadores baseados em pipe transmitem os quadros capturados por um pipe para um processo externo. As variantes baseadas em tubos tendem a ser mais eficientes, mas podem não funcionar em todos os sistemas.

FFMpegWriter

Gravador ffmpeg baseado em pipe.

ImageMagickWriter

GIF animado baseado em tubos.

Os escritores baseados em arquivo salvam arquivos temporários para cada quadro que são unidos em um único arquivo no final. Embora mais lentos, esses gravadores podem ser mais fáceis de depurar.

FFMpegFileWriter

Gravador ffmpeg baseado em arquivo.

ImageMagickFileWriter

Escritor de gif animado baseado em arquivo.

As classes do gravador fornecem uma maneira de obter quadros sequenciais do mesmo arquivo Figure. Todos eles fornecem três métodos que devem ser chamados em sequência:

  • setupprepara o escritor (por exemplo, abrindo um cachimbo). Os escritores baseados em pipe e baseados em arquivo usam argumentos diferentes para arquivos setup().

  • grab_framepode então ser chamado sempre que necessário para capturar um único quadro de cada vez

  • finishfinaliza o filme e grava o arquivo de saída no disco.

Exemplo:

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

Se estiver usando as classes do gravador diretamente (não por meio Animation.savede ), é altamente recomendável usar o savinggerenciador de contexto:

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

para garantir que a configuração e a limpeza sejam executadas conforme necessário.

Exemplos #

Classes Auxiliares #

Classes básicas de animação #

Animation

Uma classe base para animações.

TimedAnimation

Animationsubclasse para animação baseada em tempo.

Registro do gravador #

Um registro em nível de módulo é fornecido para mapear entre o nome do gravador e a classe para permitir que uma string seja transmitida em Animation.savevez de uma instância do gravador.

MovieWriterRegistry

Registro de classes de gravador disponíveis por nome legível por humanos.

Classes básicas do Writer #

Para reduzir classes base de duplicação de código

AbstractMovieWriter

Classe base abstrata para escrever filmes, fornecendo uma maneira de obter quadros chamando grab_frame.

MovieWriter

Classe base para escrever filmes.

FileMovieWriter

MovieWriterpara gravar em arquivos individuais e costurar no final.

e mixins

FFMpegBase

Classe Mixin para saída FFMpeg.

ImageMagickBase

Classe Mixin para saída do ImageMagick.

são fornecidos.

Consulte o código-fonte para saber como implementar facilmente novas MovieWriterclasses.