Источник: Nuances of Programming
Matplotlib и Seaborn — вполне приличные Python-библиотеки для создания превосходных графиков. Но такие графики получаются статичными, и крайне трудно подобрать для них красивое представление данных или отследить динамику изменений. Вам бы понравилось, если бы в своей следующей презентации/видео/посте в соцсетях вы бы смогли показать динамику изменений в виде короткого видеоролика? И даже больше: такие графики можно было бы создать в Matplotlib, Seaborn или любой другой библиотеке!
Не так давно я создал несколько динамических графиков для короткой документалки об опиоидном кризисе в США, так что данные для статьи будут браться оттуда. Эта информация размещена в открытом доступе на сайтах Национального института по изучению злоупотребления наркотиками и Центра по контролю и профилактике заболеваний. Скачать можно по ссылке: https://www.drugabuse.gov/sites/default/files/overdose_data_1999-2015.xls.
Строить графики я буду в Matplotlib и Seaborn, а для обработки данных воспользуюсь Numpy и Pandas. Matplotlib предлагает несколько функций для анимации. Так что давайте начнем и импортируем все зависимости.
Теперь для подготовки к созданию анимации нужно загрузить данные и добавить их в Pandas DataFrame. При создании нескольких графиков, о передозировке различными опиатами, лучше написать отдельную функцию, которая будет подгружать данные из нужной строки.
Давайте приступим к делу и перейдем к созданию анимации!
Во-первых, если вы, как и я, пользуетесь Jupiter Notebook, то начните ячейку с %matplotlib notebook— так вы увидите анимацию сразу, а не только после сохранения.
Лично я извлекал статистику по передозировке героином из таблицы с помощью функции get_data, а затем переносил данные в Pandas DataFrame в две колонки. Первая — год, вторая — количество передозировок.
Далее инициируемwriter, который использует ffmpeg и пишет 20 кадров в секунду с битрейтом 1800. Конечно же, эти значения вы можете настроить сами.
Writer = animation.writers['ffmpeg']
writer = Writer(fps=20, metadata=dict(artist='Me'), bitrate=1800)
Теперь создадим график с обозначениями. Обязательно задавайте пределы для осей Х и У — так анимация не будет «скакать» по диапазону отображаемых данных.
Основной компонент графика — функция анимации, которой вы задаете, что должно происходить в каждом кадре видео. Здесь i — индекс кадра анимации. Данным индексом вы выделяете диапазон данных, которые должны показываться в кадре. Затем выстраиваете эти данные в seaborn lineplot. Две последние строчки нужны для красоты.
Запуск анимации делается через matplotlib.animation.FuncAnimation — там вы привязываете функцию анимации и задаете общее количество кадров. frames определяет частоту, с которой будет вызыватьсяanimate(i).
ani = matplotlib.animation.FuncAnimation(fig, animate, frames=17, repeat=True)
Для сохранения анимации в mp4 смело вызывайте ani.save() . Если вам нужен предпросмотр перед сохранением, то лучше воспользуйтесь plt.show() .
ani.save('HeroinOverdosesJumpy.mp4', writer=writer)
Теперь анимация выглядит вот так:
Функция заработала, но переходы между данными слишком резкие. Для сглаживания прыгающих значений необходимо добавить несколько дополнительных точек между уже существующими. Для этого воспользуемся другой функцией, которую я назвал augment .
Теперь осталось применить эту функцию к данным и увеличить количество кадров в matplotlib.animation.FuncAnimation. Здесь я задаю augment с numsteps=10. Это означает, что я увеличиваю набор данных до 160 точек и указываю frames=160 . Результат получается более сглаженным, однако на графике до сих пор присутствует несколько острых пиков.
Чтобы убрать эту «остроту» можно добавить сглаживающую функцию отсюда: https://www.swharden.com/wp/2008-11-17-linear-data-smoothing-in-python/
sns.set(rc={'axes.facecolor':'lightgrey', 'figure.facecolor':'lightgrey','figure.edgecolor':'black','axes.grid':False})
Так мы получаем окончательный вариант, показанный выше.
В данной статье мы разобрали функцию анимации в matplotlib на одном примере. Конечно же, с ее помощью можно анимировать любые типы графиков. Просто настройте параметры и тип графика в функции animate() и вы получите бескрайние возможности!
Читайте нас в телеграмме и vk
Перевод статьи Viviane: How to Create Animated Graphs in Python