matplotlib.animation
Содержание
Анимация
Самый простой способ создать анимированное изображение в Matplotlib — использовать один из Animation классов.
Базовый класс для анимаций. | |
Создает анимацию путем многократного вызова функции func. | |
Анимация, использующая фиксированный набор объектов |
В обоих случаях крайне важно сохранить ссылку на экземпляр объекта. Анимация продвигается таймером (обычно из фреймворка графического интерфейса пользователя), к которому объект 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 и теории работы «блиттинга».
Ожидаемая подпись 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 для «связывания» художников с функцией. Третий метод — использовать замыкания для построения необходимых художников и функций. Четвертый метод — создать класс.
Примеры
ArtistAnimation
Примеры
Классы записи
Предоставленные классы записи делятся на несколько широких категорий.
Запись Pillow опирается на библиотеку Pillow для записи анимации, сохраняя все данные в памяти.
Класс записи HTML генерирует анимации на основе JavaScript.
Запись для JavaScript-анимаций в HTML. |
Записи на основе канала передают захваченные кадры через канал во внешний процесс. Варианты на основе канала, как правило, более эффективны, но могут не работать на всех системах.
Запись ffmpeg на основе канала. | |
Анимированные GIF на основе канала. |
Записи на основе файла сохраняют временные файлы для каждого кадра, которые склеиваются в один файл в конце. Хотя медленнее, эти записи могут быть легче отладить.
Запись ffmpeg на основе файла. | |
Запись анимированных 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.save вместо экземпляра записи.
Реестр доступных классов записи по удобочитаемому имени. |
Базовые классы записи
Для сокращения дублирования кода предоставляются базовые классы
Абстрактный базовый класс для записи видео, предоставляющий способ получения кадров с помощью вызова | |
Базовый класс для записи видео. | |
|
и миксины
Класс-смеситель для вывода FFMpeg. | |
Класс-смеситель для вывода ImageMagick. |
предоставлены.
См. исходный код, чтобы узнать, как легко реализовать новые классы MovieWriter.
© 2012–2023 Matplotlib Development Team. All rights reserved.
Licensed under the Matplotlib License Agreement.
https://matplotlib.org/3.6.0/api/animation_api.html