Время прочтения: 5 мин.
Анимация построения графиков в Matplotlib может быть реализована несколькими способами. В данном посте рассмотрю два из них:
- первый способ заключается в объединении кадров в анимационный файл;
- второй способ использует функции matplotlib.animation.FuncAnimation
Для начала создам датасет с абстрактными данными, который буду использовать для визуализации работы анимации. Так как при работе с набором данных чаще всего используют Pandas DataFrame, то и генерацию данных осуществлю непосредственно в нём.
# импортируем необходимые для генерации DataFrame библиотеки
import pandas as pd # версия 1.1.5
import numpy as np # версия 1.18.5
import random
# объявляем «переменные»
df = pd.DataFrame()
max_sum = 2000
stroki = 50 # количество строк в DataFrame
# генерируем дата сет в DataFrame
df['sum'] = np.random.choice(range(100, max_sum),stroki)
df['count'] = np.random.choice(range(1,20),stroki)
df['avg_sum'] = round(df['sum']/df['count'],1)
# Посмотрим содержимое DataFrame
df.head()
sum count avg_sum
0 157 38 4.1
1 407 37 11.0
2 461 146 3.2
3 1277 190 6.7
4 1345 58 23.2
На выходе получаю DataFrame, содержащий три столбца и пятьдесят строк. При работе с реальными данными можно осуществить импорт данных в DataFrame из файлов или использовать готовый DataFrame.
Сохраню полученный DataFrame в CSV файл для использования во втором способе анимации.
# импортируем библиотеки для работы с файловой системой
import glob
import os
import shutil
# запоминаем текущую папку
path_script = os.getcwd()
# сохраним полученный датасет для использования во втором способе
df.to_csv(path_script + '/dataset.csv', index = False)
После создания / импорта датасета приступлю непосредственно к анимированию.
Первый способ заключается в генерации файлов (кадров) в графическом формате и их дальнейшем объединении в анимированный файл. Далее перехожу к генерации кадров:
# импортируем необходимые библиотеки для генерации кадров
import moviepy.editor as mpy # версия 1.0.3
import matplotlib.pyplot as plt #3.3.4
# при необходимости импортируем библиотеки
pip install moviepy
# задаем имя папки, в которую будем складывать кадры
dir_name = 'pngs'
# создаем папку, в которую будем складывать кадры
os.mkdir(os.path.join(path_script, dir_name))
# задаем имя файла анимации
gif_name = 'anim_var1.gif'
# в цикле бежим по DataFrame, отрисовываем графики и сохраняем кадры
for i in range(0,len(df.index)):
# задаем:
# столбцы DateFrame, из которых берем данные,
# размер холста,
# толщину линии,
# цвет линий
ax = df[['sum', 'count', 'avg_sum']].iloc[:i+1].plot(figsize = (12,8), linewidth = 2, color= ['b','g','r'])
# задаем лимиты по осям
ax.set_xlim(0, i+1)
ax.set_ylim(0, max_sum)
# задаем названия осей и титул графика и размеры шрифта
ax.set_xlabel('x label', fontsize = 12)
ax.set_ylabel('y label', fontsize = 12)
ax.set_title('Title', fontsize = 18)
# задаем легенду графика, оформление
ax.legend(['Сумма', 'Кол-во', 'Ср.сумм'], loc = 'upper left', frameon = False)
# убираем ненужные оси
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# линии сетки по оси Х
ax.grid(axis = 'x')
# отрисовываем данные на холсте
fig = ax.get_figure()
# сохраняем холст в файл
fig.savefig(os.path.join(path_script, dir_name) + f'/{i}.png')
После отработки получаю набор файлов в папке, из которых далее буду формировать анимацию.
# задаем частоту кадров в секунду
fps = 5
# создаем список файлов-кадров из ранее созданной папки
file_list = glob.glob(os.path.join(path_script, dir_name) + '/*')
# создаем анимацию из списка файлов
clip = mpy.ImageSequenceClip(file_list, fps = fps)
# сохраняем анимацию в формате GIF в папку со скриптом
clip.write_gif(path_script + '/{}'.format(gif_name), fps = fps)
# удаляем папку с файлами кадров
shutil.rmtree(os.path.join(path_script, dir_name))
В результате работы скрипта получается файл в формате GIF, который содержит анимацию построения графика по данным из датасета.

Во втором способе для сравнения анимаций использую датасет из предыдущего примера. В этом способе буду использовать стандартную функцию animate библиотеки matplotlib.
# импортируем необходимые библиотеки
import pandas as pd
import os
# при необходимости импортируем библиотеки
pip install Pillow # версия 8.4.0
# запоминаем текущую папку
path_script = os.getcwd()
# прочитаем датасет из первого способа
df = pd.read_csv(path_script + '/dataset.csv')
# импортируем необходимые библиотеки
import matplotlib.pyplot as plt
import matplotlib.animation as animation
# инициализируем холст, задаем размер
fig,ax = plt.subplots(figsize = (12,8))
# задаем лимиты по осям
ax.set_xlim(0, len(df.index) + 1)
ax.set_ylim(0, max_sum)
# задаем названия осей и титул графика и размеры шрифта
ax.set_xlabel('x label', fontsize = 12)
ax.set_ylabel('y label', fontsize = 12)
ax.set_title('Title', fontsize = 18)
# убираем ненужные оси
ax.spines['right'].set_visible(False)
ax.spines['top'].set_visible(False)
# линии сетки по оси Х
ax.grid(axis = 'x')
# объявляем «переменные» для координат графиков
x = []
y_sum = []
y_count = []
y_avg_sum = []
# функция анимации
def animate(i):
# задаем легенду графика, оформление
ax.legend(['Сумма', 'Кол-во', 'Ср.сумм'], loc = 'upper left', frameon = False)
# прописываем функции координат
x.append(i)
y_sum.append(df['sum'].iloc[i])
y_count.append(df['count'].iloc[i])
y_avg_sum.append(df['avg_sum'].iloc[i])
# отображаем графики на холсте
ax.plot(x,y_sum, 'b')
ax.plot(x,y_count, 'g')
ax.plot(x,y_avg_sum, 'r')
# создаем анимацию
anim = animation.FuncAnimation(fig, animate, frames = len(df.index), interval = len(df.index))
# сохраняем анимацию в формате GIF в папку со скриптом
anim.save(os.getcwd() + '/anim_var2.gif', fps = 5, writer = 'pillow')

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