Spec-Zone.ru › Matplotlib 3.5

matplotlib.animation

Оглавление

  • Диаграммы наследования
  • Анимация
  • Классы-писатели
  • Вспомогательные классы

Диаграммы наследования

Inheritance diagram of matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation
Inheritance diagram of matplotlib.animation.FFMpegFileWriter, matplotlib.animation.FFMpegWriter, matplotlib.animation.ImageMagickFileWriter, matplotlib.animation.ImageMagickWriter

Анимация

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

Animation

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

FuncAnimation

Создание анимации путём многократного вызова функции func.

ArtistAnimation

Анимация с использованием фиксированного набора объектов Artist.

В обоих случаях крайне важно сохранять ссылку на экземпляр объекта. Анимация продвигается таймером (обычно из фреймворка GUI), и у объекта 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, = plt.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 для «связывания» элементов с функцией. Третий метод — использование замыканий для создания необходимых элементов и функций. Четвёртый — создание класса.

Примеры

  • Затухание
  • Обновление Байеса
  • Двойной маятник
  • Анимированная гистограмма
  • Анимация дождя
  • Анимированная 3D случайная прогулка
  • Анимированная линия графика
  • Осциллограф
  • MATPLOTLIB НЕПРЯМОЕ УПРАВЛЕНИЕ

ArtistAnimation

Примеры

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

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

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

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

PillowWriter

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

HTMLWriter

Запись для HTML-видео на основе JavaScript.

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

FFMpegWriter

Запись ffmpeg, основанная на каналах.

ImageMagickWriter

Анимированный GIF, основанный на каналах.

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

FFMpegFileWriter

Запись ffmpeg, основанная на файлах.

ImageMagickFileWriter

Запись анимированного GIF, основанная на файлах.

В основе MovieWriter лежит возможность получения последовательных кадров из одного базового объекта Figure. Базовый класс MovieWriter реализует 3 метода и менеджер контекста. Единственное отличие между классами записи, основанными на каналах и файлах, заключается в аргументах их соответствующих методов 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

Абстрактный базовый класс для записи фильмов.

MovieWriter

Базовый класс для записи фильмов.

FileMovieWriter

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

и миксины

FFMpegBase

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

ImageMagickBase

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

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

См. исходный код, чтобы узнать, как легко реализовать новые классы MovieWriter.

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

Spec-Zone.ru

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