Spec-Zone.ru › Matplotlib 3.7

matplotlib.animation

Оглавление

  • Анимация
  • Классы писателей
  • Вспомогательные классы

Анимация

Самый простой способ создать живую анимацию в Matplotlib — использовать один из классов Animation.

Inheritance diagram of matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation

Animation

Базовый класс для анимаций.

FuncAnimation

Подкласс TimedAnimation, создающий анимацию путём многократного вызова функции func.

ArtistAnimation

Подкласс TimedAnimation, создающий анимацию, используя фиксированный набор объектов Artist.

В обоих случаях очень важно сохранить ссылку на объект экземпляра. Анимация продвигается таймером (обычно из среды графического интерфейса хоста), и объект Animation хранит единственную ссылку на него. Если вы не сохраняете ссылку на объект Animation, он (а вместе с ним и таймеры) будет собран сборщиком мусора, что остановит анимацию.

Для сохранения анимации используйте Animation.save, Animation.to_html5_video или Animation.to_jshtml.

Подробные сведения о поддерживаемых форматах кинофильмов см. в разделе Вспомогательные классы ниже.

FuncAnimation

Внутренняя работа FuncAnimation примерно такая:

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

с деталями для обработки «блека» (чтобы значительно улучшить производительность в реальном времени), быть неблокирующим, не запускать/останавливать цикл обработки событий GUI многократно, обрабатывать повторы, несколько осей анимации и легко сохранять анимацию в файл кинофильма.

«Блека» — это стандартный приём в компьютерной графике. В целом, суть заключается в том, чтобы взять существующий битмап (в нашем случае в основном растровое изображение) и затем «блекнуть» еще один объект сверху. Таким образом, управляя сохранённым «чистым» битмапом, мы можем перерисовать только несколько изменяющихся объектов на каждом кадре и, возможно, сэкономить значительное время. Когда мы используем блёка (передавая blit=True), основной цикл FuncAnimation становится немного сложнее:

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)

Конечно, это не учитывает многие детали (такие как обновление фона при изменении размера или полном перерисовывании фигуры). Однако, надеюсь, этот минималистичный пример даёт представление о том, как init_func и func используются внутри FuncAnimation и теории работы «блека».

Примечание

Порядок z объектов не учитывается при «блеке», так как «блекнутые» объекты всегда рисуются поверх.

Ожидаемая подпись для func и init_func очень простая, чтобы освободить FuncAnimation от вашей логики хранения и построения графиков, но это означает, что вызываемые объекты, которые вы передаёте, должны знать, на каких объектах им следует работать. Существует несколько подходов к решению этой проблемы, от простого до более сложного. Самый простой подход, который отлично работает в случае скрипта, — это определить объект в глобальной области и позволить Python разобраться.

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

Второй метод заключается в использовании functools.partial для передачи аргументов в функцию:

import numpy as np
import matplotlib.pyplot as plt
from matplotlib.animation import FuncAnimation
from functools import partial

fig, ax = plt.subplots()
line1, = ax.plot([], [], 'ro')

def init():
    ax.set_xlim(0, 2*np.pi)
    ax.set_ylim(-1, 1)
    return line1,

def update(frame, ln, x, y):
    x.append(frame)
    y.append(np.sin(frame))
    ln.set_data(x, y)
    return ln,

ani = FuncAnimation(
    fig, partial(update, ln=line1, x=[], y=[]),
    frames=np.linspace(0, 2*np.pi, 128),
    init_func=init, blit=True)

plt.show()

Третий метод — использование замыканий для построения необходимых объектов и функций. Четвёртый метод — создание класса.

Примеры

  • Распад
  • Обновление Байеса
  • Задача двойного маятника
  • Анимированная гистограмма
  • Моделирование дождя
  • Анимированная 3D случайная прогулка
  • Анимированный график линии
  • Осциллограф
  • MATPLOTLIB UNCHAINED

ArtistAnimation

Примеры

  • Анимированное изображение с помощью предварительно вычисленного списка изображений

Классы записи

Inheritance diagram of matplotlib.animation.FFMpegFileWriter, matplotlib.animation.FFMpegWriter, matplotlib.animation.ImageMagickFileWriter, matplotlib.animation.ImageMagickWriter, matplotlib.animation.PillowWriter, matplotlib.animation.HTMLWriter

Предоставленные классы записи можно разделить на несколько основных категорий.

Класс PillowWriter использует библиотеку Pillow для записи анимации, сохраняя все данные в памяти.

PillowWriter

Класс HTMLWriter генерирует анимации на основе JavaScript.

HTMLWriter

Запись для JavaScript-анимаций HTML.

Классы записи, основанные на каналах, передают захваченные кадры по каналу во внешний процесс. Варианты на основе каналов, как правило, более производительны, но могут не работать на всех системах.

FFMpegWriter

Запись ffmpeg на основе канала.

ImageMagickWriter

Запись анимированных GIF на основе канала.

Классы записи, основанные на файлах, сохраняют временные файлы для каждого кадра, которые склеиваются в один файл в конце. Хотя это медленнее, эти классы могут быть легче отлаживаться.

FFMpegFileWriter

Запись ffmpeg на основе файла.

ImageMagickFileWriter

Запись анимированных GIF на основе файла.

Классы записи предоставляют способ получения последовательных кадров из одного и того же базового Figure. Все они предоставляют три метода, которые должны вызываться последовательно:

  • setup подготавливает класс записи (например, открывает канал). Классы записи на основе каналов и файлов принимают разные аргументы для setup().
  • grab_frame можно вызывать столько раз, сколько нужно, для захвата одного кадра за раз
  • finish завершает видеоролик и записывает выходной файл на диск.

Пример:

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

При использовании классов записи напрямую (а не через Animation.save), настоятельно рекомендуется использовать менеджер контекста saving:

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

для обеспечения выполнения необходимой настройки и очистки.

Примеры

  • Захват кадров

Вспомогательные классы

Базовые классы анимации

Animation

Базовый класс для анимаций.

TimedAnimation

Подкласс Animation для анимации, основанной на времени.

Регистр записей

Предоставлен модульный регистр для сопоставления имени класса записи с самим классом. Это позволяет передавать строку в Animation.save вместо экземпляра класса.

MovieWriterRegistry

Регистр доступных классов записи по удобочитаемому имени.

Базовые классы записывателей

Для сокращения дублирования кода

AbstractMovieWriter

Абстрактный базовый класс для записи видеороликов, предоставляющий способ получения кадров, вызывая grab_frame.

MovieWriter

Базовый класс для записи видеороликов.

FileMovieWriter

MovieWriter для записи в отдельные файлы и склейки в конце.

и миксинов

FFMpegBase

Класс-миксин для вывода FFMpeg.

ImageMagickBase

Класс-миксин для вывода ImageMagick.

предоставлены.

См. исходный код для простого внедрения новых MovieWriter классов.

© 2012–2023 Matplotlib Development Team. All rights reserved.
Licensed under the Matplotlib License Agreement.
https://matplotlib.org/3.7.5/api/animation_api.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API