Spec-Zone.ru › Matplotlib 3.8

matplotlib.animation

Содержание

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

Анимация

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

Диаграмма наследования matplotlib.animation.FuncAnimation, matplotlib.animation.ArtistAnimation

Animation

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

FuncAnimation

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

ArtistAnimation

Подкласс TimedAnimation, который создаёт анимацию с помощью фиксированного набора объектов 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 и о теории работы «блиттинга».

Примечание

Порядок 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

Примеры

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

Классы Writer

Диаграмма наследования matplotlib.animation.FFMpegFileWriter, matplotlib.animation.FFMpegWriter, matplotlib.animation.ImageMagickFileWriter, matplotlib.animation.ImageMagickWriter, matplotlib.animation.PillowWriter, matplotlib.animation.HTMLWriter

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

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

PillowWriter

Пишущий HTML генерирует анимацию на основе 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

Mixin-класс для вывода FFMpeg.

ImageMagickBase

Mixin-класс для вывода ImageMagick.

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

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

Spec-Zone.ru

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