Анимация
Оглавление
Анимация
Самый простой способ создать живую анимацию в matplotlib — использовать один из классов Animation.
FuncAnimation | Создаёт анимацию путём многократного вызова функции func. |
ArtistAnimation | Анимация, использующая набор Artist объектов. |
В обоих случаях крайне важно сохранить ссылку на экземпляр объекта. Анимация продвигается таймером (как правило, из фреймворка графического интерфейса), который удерживает единственную ссылку на объект Animation. Если вы не сохраняете ссылку на объект Animation, он (и, следовательно, таймеры) будут удалены сборщиком мусора, что остановит анимацию.
Для сохранения анимации на диск используйте Animation.save или Animation.to_html5_video.
См. Вспомогательные классы ниже для получения подробной информации о поддерживаемых форматах видео.
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, = plt.plot([], [], 'ro', animated=True)
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 для «привязки» объектов к функциям. Третий метод — использовать замыкания для создания необходимых объектов и функций. Четвёртый метод — создать класс.
Примеры
- Затухание
- Обновление Байеса
- Задача двойного маятника
- Анимированная гистограмма
- Моделирование дождя
- Анимированная 3D случайная прогулка
- Анимированная линия графика
- Осциллограф
- MATPLOTLIB НЕПРИВЯЗАННЫЙ
ArtistAnimation
Примеры
Классы записи
Предоставленные классы записи делятся на несколько основных категорий.
Класс записи Pillow использует библиотеку Pillow для записи анимации, сохраняя все данные в памяти.
PillowWriter |
Классы записи, основанные на каналах, передают захваченные кадры через канал во внешний процесс. Такие классы, как правило, более производительны, но могут не работать на всех системах.
FFMpegWriter | Запись в формате ffmpeg через канал. |
ImageMagickWriter | Анимированный GIF через канал. |
AVConvWriter | Запись в формате avconv через канал. |
Классы записи, основанные на файлах, сохраняют временные файлы для каждого кадра, которые впоследствии соединяются в один файл. Хотя такие классы медленнее, они могут быть проще в отладке.
FFMpegFileWriter | Запись в формате ffmpeg, работающая с файлами. |
ImageMagickFileWriter | Запись анимированного GIF, работающая с файлами. |
AVConvFileWriter | Запись в формате avconv, работающая с файлами. |
В основе MovieWriter лежит возможность извлечения последовательных кадров из одного и того же базового объекта Figure. Базовый класс MovieWriter реализует 3 метода и менеджер контекста. Единственное различие между классами записи, работающими с каналами, и классами записи, работающими с файлами, заключается в аргументах для методов setup.
Метод setup() используется для подготовки записи (возможно, открытия канала), последующие вызовы grab_frame() захватывают один кадр за раз, и finish() завершает создание фильма и записывает выходной файл на диск. Например
moviewriter = MovieWriter(...)
moviewriter.setup(fig=fig, 'my_movie.ext', dpi=100)
for j in range(n):
update_figure(n)
moviewriter.grab_frame()
moviewriter.finish()
При непосредственном использовании классов записи (не через Animation.save), настоятельно рекомендуется использовать менеджер контекста saving
with moviewriter.saving(fig, 'myfile.mp4', dpi=100):
for j in range(n):
update_figure(n)
moviewriter.grab_frame()
для обеспечения необходимого выполнения действий по настройке и очистке.
Примеры
Вспомогательные классы
Базовые классы анимации
Animation | Этот класс оборачивает создание анимации с использованием matplotlib. |
TimedAnimation |
Подкласс Animation для анимации по времени. |
Регистр записи
Для сопоставления между именем записи и классом предоставляется регистр на уровне модуля, позволяющий передать строку в Animation.save вместо экземпляра записи.
MovieWriterRegistry | Регистр доступных классов записи по удобочитаемому имени. |
Базовые классы записи
Для уменьшения дублирования кода базовые классы
AbstractMovieWriter | Абстрактный базовый класс для записи видео. |
MovieWriter | Базовый класс для записи видео. |
FileMovieWriter |
MovieWriter для записи в отдельные файлы и склейки в конце. |
и миксины
AVConvBase | Миксин-класс для вывода avconv. |
FFMpegBase | Миксин-класс для вывода FFMpeg. |
ImageMagickBase | Миксин-класс для вывода ImageMagick. |
предоставляются.
Обратитесь к исходному коду, чтобы узнать, как легко реализовать новые классы MovieWriter.
Диаграммы наследования
© 2012–2018 Matplotlib Development Team. All rights reserved.
Licensed under the Matplotlib License Agreement.
https://matplotlib.org/3.0.0/api/animation_api.html