Matplotlib ArtistAnimation: Постройте всю фигуру на каждом шаге - PullRequest
0 голосов
/ 07 мая 2020

У меня есть существующая функция, которую я использую для построения графика, которую я постоянно вызываю в своей программе. Я хочу использовать matplotlib s ArtistAnimation, чтобы сохранить каждый сюжет как «художник», который показан на одном этапе анимации.

Я знаю, как использовать ArtistAnimation для отображения отдельных элементов сюжет в анимации, но не весь сюжет.

Вот упрощенный пример:

import random

def my_plot():
    fig, ax = plt.subplots()
    ax.plot([random.randrange(10), random.randrange(10)], [random.randrange(10), random.randrange(10)])
    ax.plot([random.randrange(10), random.randrange(10)], [random.randrange(10), random.randrange(10)])
    plt.show()
    return ax

ims = []
fig = plt.figure()
for _ in range(5):
    ax = my_plot()
    ims.append((ax,))
ani = animation.ArtistAnimation(fig, ims, repeat=False)
ani.save('im.mp4', metadata={'artist':'Guido'})

Это выполняется без ошибок, но полученное видео остается пустым. То же самое произойдет, если я верну список художников, созданных ax.plot().

. Я предполагаю, что проблема в том, что я звоню plt.figure / plt.subfigure несколько раз. Но я не знаю, как этого избежать. Нужно ли мне создавать одну фигуру и передавать ее каждому вызову my_plot? Выглядит немного некрасиво.

Ответы [ 2 ]

2 голосов
/ 13 мая 2020

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

import matplotlib.pyplot as plt
from matplotlib import animation
import random

def my_plot(ax):
    p0, = ax.plot([random.randrange(10), random.randrange(10)], [random.randrange(10), random.randrange(10)])
    p1, = ax.plot([random.randrange(10), random.randrange(10)], [random.randrange(10), random.randrange(10)])
    return [p0, p1]   # return a list of the new plots

ims = []
fig = plt.figure()
ax = fig.add_subplot(111)  # fig and axes created once
for _ in range(10):
    ps = my_plot(ax)
    ims.append(ps)      # append the new list of plots
ani = animation.ArtistAnimation(fig, ims, repeat=False)
ani.save('im.mp4', metadata={'artist':'Guido'})

GIF ниже, но вот небольшой интервал по вертикали, чтобы вы могли прокручивать надоедливые мигающие строки страницы во время чтения кода

.
.
.
.
.
.
.
.
.
.
.
.
.
.

enter image description here

0 голосов
/ 13 мая 2020

Благодаря ответу Тома я нашел основные причины, по которым мои анимации не работали, и показывал только первый кадр: я называл plt.show() на каждой итерации. Видно после первого звонка перестают работать анимации. Удаление plt.show() и создание только одной фигуры решило проблему:

import matplotlib.pyplot as plt
from matplotlib import animation
import random

def my_plot():
    patch = []
    patch.extend(plot([random.randrange(10), random.randrange(10)], [random.randrange(10), random.randrange(10)]))
    patch.extend(plt.plot([random.randrange(10), random.randrange(10)], [random.randrange(10), random.randrange(10)]))
    # no plt.show() here!
    return patch

ims = []
fig = plt.figure()   # fig created only once
for _ in range(10):
    patch = my_plot()
    ims.append(patch)  
ani = animation.ArtistAnimation(fig, ims, repeat=False)
ani.save('im.mp4', metadata={'artist':'Guido'})

Не уверен, как я могу построить и показать графики напрямую и создать анимацию. Может быть, вместо этого использовать plt.draw()? Но это ничего не показывает в моей PyCharm IDE ... В любом случае, я могу жить с любым или.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...