Используем библиотеку matplotlib для создания интересной анимации
Изображение имитации дождя выполнено с помощью библиотеки Matplotlib, известной как прародитель пакетов для визуализации данных на python. Matplotlib имитирует капли дождя на поверхности путем анимирования масштаба и непрозрачности 50 точек графика разброса. В этой статье мы рассмотрим анимации в Matplotlib и несколько способов их создания.
Обзор
Matplotlib — это одна из самых известных библиотек Python с двумерной (2D) графикой. Многие начинают путешествие в мир визуализации данных с Matplotlib. С ее помощью можно с легкостью создавать графики, гистограммы, энергетические спектры, столбчатые диаграммы, графики погрешностей, графики разброса и многое другое. Она также интегрируется с такими библиотеками, как Pandas и Seaborn для создания более сложных визуализаций.
Некоторые особенности matplotlib:
- Она разработана подобно MATLAB, поэтому переключаться между ними довольно просто.
- Содержит множество расширений для визуализации.
- Воспроизводит практически все графики (если приложить усилия).
- Существует более десяти лет, соответственно обладает большой базой пользователей.
Однако в некоторых областях Matplotlib отстает от своих мощных противников.
- Matplotlib обладает достаточно многословным императивным API.
- Иногда встречаются слабые по стилю стандартные параметры.
- Слабая поддержка веб и интерактивных графов.
- Часто тормозит при наличии большого объема сложных данных.
Освежить знания о базовых функциях поможет шпаргалка по Matplotlib из Datacamp.
Анимации
Базовый класс animation в Matplotlib отвечает за анимацию. Он предоставляет основу, вокруг которой создается функциональность анимации. Для этого есть два основных интерфейса:
FuncAnimation создает анимацию с помощью повторения вызова функции func.
ArtistAnimation: анимация с использованием фиксированного набора объектов Artist.
FuncAnimation является более удобным способом. В документации можно ознакомиться с обоими способами подробнее. В этой статье мы будем использовать только инструмент FuncAnimation.
Требования
- Установите модули, включая numpy и matplotlib
- Установите ffmpeg или imagemagick для сохранения анимации в формате mp4 или gif.
Теперь можно перейти к созданию базовой анимации в Jupyter Notebooks. Код доступен в репозитории Github.
Базовая анимация: Движущаяся синусоидальная волна
Создадим базовую анимацию синусоидальной волны, движущейся по экрану, с помощью FuncAnimation. Исходный код для этой анимации взят из Руководства по анимации в Matplotlib. Рассмотрим входные данные, а затем разберем отдельные фрагменты кода.
import numpy as np from matplotlib import pyplot as plt from matplotlib.animation import FuncAnimation plt.style.use('seaborn-pastel') fig = plt.figure() ax = plt.axes(xlim=(0, 4), ylim=(-2, 2)) line, = ax.plot([], [], lw=3) def init(): line.set_data([], []) return line, def animate(i): x = np.linspace(0, 4, 1000) y = np.sin(2 * np.pi * (x - 0.01 * i)) line.set_data(x, y) return line, anim = FuncAnimation(fig, animate, init_func=init, frames=200, interval=20, blit=True) anim.save('sine_wave.gif', writer='imagemagick')
- В строках 7–9 создаем фигуру window с одной осью. Затем создаем пустой объект line, единственный из объектов, который будет изменяться в анимации. Объект line будет заполнен данными позже.
- В строках 11–13 создаем функцию init, осуществляющую анимацию. Функция init инициализирует данные и устанавливает пределы оси.
- В строках 14–18 определяем функцию, которая принимает количество кадров (i) в качестве параметра и создает синусоидальную волну (или любую другую анимацию), выполняющую движения в зависимости от значения i. Эта функция возвращает кортеж измененных объектов графика, который сообщает фреймворку анимации, какие части графика нужно анимировать.
- В строке 20 создаем объект animation. Параметр blit гарантирует, что будут перерисованы только измененные части графика.
Это базовый подход к созданию анимации в Matplotlib. При внесении небольших изменений в код можно создать более интересные визуализации. Рассмотрим некоторые из них.
Растущая спираль
Создадим движущуюся спираль, которая будет медленно разматываться, с помощью класса animation в matplotlib. Код схож с кодом графика синусоидальной волны, однако содержит несколько изменений.
import matplotlib.pyplot as plt import matplotlib.animation as animation import numpy as np plt.style.use('dark_background') fig = plt.figure() ax = plt.axes(xlim=(-50, 50), ylim=(-50, 50)) line, = ax.plot([], [], lw=2) # initialization function def init(): # creating an empty plot/frame line.set_data([], []) return line, # lists to store x and y axis points xdata, ydata = [], [] # animation function def animate(i): # t is a parameter t = 0.1*i # x, y values to be plotted x = t*np.sin(t) y = t*np.cos(t) # appending new points to x, y axes points list xdata.append(x) ydata.append(y) line.set_data(xdata, ydata) return line, # setting a title for the plot plt.title('Creating a growing coil with matplotlib!') # hiding the axis details plt.axis('off') # call the animator anim = animation.FuncAnimation(fig, animate, init_func=init, frames=500, interval=20, blit=True) # save the animation as mp4 video file anim.save('coil.gif',writer='imagemagick')
График обновления в режиме реального времени
Графики обновления в режиме реального времени пригодятся при построении динамических величин, таких как данные о запасах, данные сенсоров и друге зависящие от времени данные. Создаем базовый граф, который обновляется автоматически при появлении новых данных в системе. Создадим график цен на акции компании за месяц.
#importing libraries import matplotlib.pyplot as plt import matplotlib.animation as animation fig = plt.figure() #creating a subplot ax1 = fig.add_subplot(1,1,1) def animate(i): data = open('stock.txt','r').read() lines = data.split('n') xs = [] ys = [] for line in lines: x, y = line.split(',') # Delimiter is comma xs.append(float(x)) ys.append(float(y)) ax1.clear() ax1.plot(xs, ys) plt.xlabel('Date') plt.ylabel('Price') plt.title('Live graph with matplotlib') ani = animation.FuncAnimation(fig, animate, interval=1000) plt.show()
Откройте терминал и запустите файл python. Получаем изображенный ниже график, который автоматически обновляется следующим образом:
Интервал составляет 1000 миллисекунд или одну секунду.
Анимация на 3D-графике
Создание 3D-графиков достаточно распространено, однако, что если анимировать угол обзора в этих графиках? Идея заключается в изменении обзора камеры и использовании каждого результирующего изображения для создания анимации. В Python Graph Gallery можно найти раздел, посвященный этой теме.
Создайте папку volcano в одном каталоге с notebook. Все изображения, которые будут использовать в анимации, сохранятся в этой папке.
# library from mpl_toolkits.mplot3d import Axes3D import matplotlib.pyplot as plt import pandas as pd import seaborn as sns # Get the data (csv file is hosted on the web) url = 'https://python-graph-gallery.com/wp-content/uploads/volcano.csv' data = pd.read_csv(url) # Transform it to a long format df=data.unstack().reset_index() df.columns=["X","Y","Z"] # And transform the old column name in something numeric df['X']=pd.Categorical(df['X']) df['X']=df['X'].cat.codes # We are going to do 20 plots, for 20 different angles for angle in range(70,210,2): # Make the plot fig = plt.figure() ax = fig.gca(projection='3d') ax.plot_trisurf(df['Y'], df['X'], df['Z'], cmap=plt.cm.viridis, linewidth=0.2) ax.view_init(30,angle) filename='Volcano/Volcano_step'+str(angle)+'.png' plt.savefig(filename, dpi=96) plt.gca()
Этот фрагмент кода создаст несколько файлов PNG в папке Volcano. Теперь используем ImageMagick для создания анимации из этих изображений. Откройте терминал, перейдите к папке Volcano и введите следующую команду:
convert -delay 10 Volcano*.png animated_volcano.gif
Анимации с использованием модуля Celluloid
Celluloid — это модуль в Python, упрощающий процесс создания анимации в matplotlib. Эта библиотека создает фигуру matplotlib и Camera из нее. Затем она использует фигуру и делает снимок с камеры после создания каждого фрейма. Наконец создается анимация из всех захваченных фреймов.
Установка
pip install celluloid
Несколько примеров использования модуля Celluloid.
Minimal
from matplotlib import pyplot as plt from celluloid import Camera fig = plt.figure() camera = Camera(fig) for i in range(10): plt.plot([i] * 10) camera.snap() animation = camera.animate() animation.save('celluloid_minimal.gif', writer = 'imagemagick')
Subplots
import numpy as np from matplotlib import pyplot as plt from celluloid import Camera fig, axes = plt.subplots(2) camera = Camera(fig) t = np.linspace(0, 2 * np.pi, 128, endpoint=False) for i in t: axes[0].plot(t, np.sin(t + i), color='blue') axes[1].plot(t, np.sin(t - i), color='blue') camera.snap() animation = camera.animate() animation.save('celluloid_subplots.gif', writer = 'imagemagick')
Legends
import matplotlib from matplotlib import pyplot as plt from celluloid import Camera fig = plt.figure() camera = Camera(fig) for i in range(20): t = plt.plot(range(i, i + 5)) plt.legend(t, [f'line {i}']) camera.snap() animation = camera.animate() animation.save('celluloid_legends.gif', writer = 'imagemagick')
Вывод
С помощью анимации можно подчеркнуть особенности визуализации, которые трудно передать с помощью статических диаграмм. Однако не стоит злоупотреблять использованием визуализаций. Каждую функцию в визуализации данных следует использовать разумно для создания лучшего эффекта.
Специально для сайта ITWORLD.UZ. Новость взята с сайта NOP::Nuances of programming