ππ ΠΠ°ΠΊ Β«ΠΎΠΆΠΈΠ²Π»ΡΡΡΒ» Π³ΡΠ°ΡΠΈΠΊΠΈ ΠΈ Π²ΠΏΠ΅ΡΠ°ΡΠ»ΡΡΡ Π²ΡΠ΅Ρ ΠΊΡΠ°ΡΠΈΠ²ΡΠΌΠΈ Π°Π½ΠΈΠΌΠ°ΡΠΈΡΠΌΠΈ Ρ ΠΏΠΎΠΌΠΎΡΡΡ Python
Разработчик ПО (системы PDM/PLM) с 1993 года, компания "ИНТЕРМЕХ" (www.intermech.ru). В 2020-м успешно закончил курсы "Основы Data Science" (минская IT Academy) Референт-переводчик технической литературы с английского языка. Показываем на примерах, как создавать красивые анимации с помощью Python, чтобы удивлять даже самых искушенных зрителей. Если статических графиков недостаточно – нарисуем постоянно меняющиеся анимации! Каждый Data Scientist знает, что важно не только получить данные, решающие некоторую задачу, но и представить эти данные в виде, удобном для восприятия людей, которые будут принимать решения на их основе. Для этого используются диаграммы, гистограммы, графики и многое другое. Но если вы хотите создать презентацию, по-настоящему привлекающую внимание – статических картинок может оказаться недостаточно. Вам потребуются динамические анимации. Когда вы прочитаете эту статью, вы сможете воссоздать график, показанный выше, и использовать полученные знания для создания собственных красивых анимаций. Будем считать, что у вас есть опыт общения с Python’ом, и вы знаете, как выполнять базовые операции манипуляции данными и рисовать графики. Предлагаемый ниже метод анимации – не единственный, и если вы знаете какой-нибудь другой, вам будет интересно сравнить их друг с другом. Мы будем использовать трехмерные линии и точки для создания траекторий, но эти же методы можно распространить на другие визуализации – например, двухмерные линии, столбчатые и секторные диаграммы, контуры и т. д. В Python’е есть куча библиотек для анализа данных и мы воспользуемся парой из них. Давайте начнем писать новый скрипт и импортируем пакеты, нужные для этого проекта: Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста» Интересно, перейти к каналу Прежде чем думать о рисовании каких-то графиков, мы должны создать данные, на основе которых мы будем рисовать графики. Для этого я создал кое-какие позиционные данные, полученные с помощью функции синуса и временного массива, содержащего значения от Этот код легко понять даже без объяснений. Вы можете поиграть с временным и позиционным массивами для задания собственных траекторий. Переменные Для анимации нашей картинки мы используем функцию Прежде всего обратим внимание на переменную Первое, что делает эта функция – очищает фигуру. Очистка уничтожает линии, точки, оси с метками и заголовок. Затем функция добавляет обновленную линию траектории (от Наконец, наша функция задает заголовок и метки наших осей. Метки очевидны: это Последний шаг – это собственно вывод нашей анимации с помощью Вы можете запустить этот код, и если все сделано правильно, ваш график должен выглядеть примерно так (скорость движения точки может быть разной): Если вы хотите сохранить свою анимацию в файл Нужно выбрать имя файла для сохранения анимации и сохранить его в переменной Мы познакомились с пакетами *** Ilya Ginsburg
Импортируем пакеты
# Импортируем пакеты import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import animation
np
для удобства).plt
для удобства).animation
из пакета Matplotlib используется для создания анимаций путем периодического вызова функции, которую мы определим позднее.Создадим набор данных
0
до 20
(я обозначил их как секунды анимации).
# Временной массив t = np.linspace(0, 20, 100) # Позиционные массивы x = np.sin(np.pi/5 * t) y = np.sin(np.pi/3 * t) z = np.linspace(0, 100, 100) # Задаем набор данных для анимации dataSet = np.array([x, y, z]) # Комбинируем наши позиционные координаты numDataPoints = len(t)
dataSet
и numDataPoints
будут использованы в нашей функции анимации, которую мы сейчас определим.Функция анимации
FuncAnimation
из импортированного класса animation
. Документацию по обоим можно найти здесь. FuncAnimation
требует, чтобы мы создали собственную функцию, обновляющую линии, точки и пр., которую мы назовем animate_func
.
def animate_func(num): ax.clear() # Очищаем фигуру для обновления линии, точки, # заголовка и осей # Обновляем линию траектории (num+1 из-за индексации Python) ax.plot3D(dataSet[0, :num+1], dataSet[1, :num+1], dataSet[2, :num+1], c='blue') # Обновляем локацию точки ax.scatter(dataSet[0, num], dataSet[1, num], dataSet[2, num], c='blue', marker='o') # Добавляем постоянную начальную точку ax.plot3D(dataSet[0, 0], dataSet[1, 0], dataSet[2, 0], c='black', marker='o') # Задаем пределы для осей ax.set_xlim3d([-1, 1]) ax.set_ylim3d([-1, 1]) ax.set_zlim3d([0, 100]) # Добавляем метки ax.set_title('Trajectory nTime = ' + str(np.round(t[num], decimals=2)) + ' sec') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_zlabel('z')
num,
передаваемую в animate_func
. Это индекс текущего шага анимации. Когда мы передаем animate_func
в FuncAnimation
, последняя будет накручивать нашу переменную num
. Мы можем использовать эту переменную для итерации по нашему dataSet’у, созданному ранее.0
до num
) и локацию точки (на шаге num
). В этой фигуре начальная точка остается неизменной, так что вы заметите, что num
не показывается, поскольку мы не меняем начальную точку. Затем функция определяет наши неизменные пределы по осям. Вы можете убрать эти пределы, если хотите, чтобы оси изменялись по мере продвижения (то есть, ваши оси станут динамическими).x
, y
, z
, обозначающие декартовы координаты. В качестве небольшой дополнительной функциональности у нас есть динамический заголовок, показывающий текущий номер итерации в повременном массиве, t
. Мы показываем эти секунды (с округлением до двух цифр после запятой) и обновляем их на каждой итерации. Заметьте, это не настоящие секунды.Рисуем нашу анимацию
FuncAnimation
. Начнем с создания объекта фигуры с трехмерными осями. Затем вызываем FuncAnimation
, принимающую фигуру, нашу функцию анимации, которую мы только что создали, а также значения interval
и frames
. Interval
– это время задержки между фреймами в миллисекундах, а frames
– это просто количество фреймов, которые нужно показать. Два последних аргумента не обязательны, но мне нравится включать их, если я хочу иметь возможность настраивать вид анимация.
# Рисуем анимацию fig = plt.figure() ax = plt.axes(projection='3d') line_ani = animation.FuncAnimation(fig, animate_func, interval=100, frames=numDataPoints) plt.show()
Сохранение нашей анимации (опционально)
.gif
, можно использовать следующий код, делающий именно это:
# Сохраняем анимацию f = r"c://Users/(Insert User)/Desktop/animate_func.gif" writergif = animation.PillowWriter(fps=numDataPoints/6) line_ani.save(f, writer=writergif)
f
. Затем можно настроить количество фреймов в секунду, fps
, передаваемое в PillowWriter
. Я разделил переменную numDataPoints
, которая определяет количество фреймов в FuncAnimation
, на 6, чтобы анимация занимала 6 секунд времени.mplot3d
и animation
, а также научились рисовать анимации графиков и сохранять эти анимации в файлы .gif
. Спасибо за прочтение!Материалы по теме
- 2 views
- 0 Comment