Ilya Ginsburg Разработчик ПО (системы PDM/PLM) с 1993 года, компания "ИНТЕРМЕХ" (www.intermech.ru). В 2020-м успешно закончил курсы "Основы Data Science" (минская IT Academy) Референт-переводчик технической литературы с английского языка. Показываем на примерах, как создавать красивые анимации с помощью Python, чтобы удивлять даже самых искушенных зрителей. Если статических графиков недостаточно – нарисуем постоянно меняющиеся анимации! Каждый Data Scientist знает, что важно не только получить данные, решающие некоторую задачу, но и представить эти данные в виде, удобном для восприятия людей, которые будут принимать решения на их основе. Для этого используются диаграммы, гистограммы, графики и многое другое. Но если вы хотите создать презентацию, по-настоящему привлекающую внимание – статических картинок может оказаться недостаточно. Вам потребуются динамические анимации. Когда вы прочитаете эту статью, вы сможете воссоздать график, показанный выше, и использовать полученные знания для создания собственных красивых анимаций. Будем считать, что у вас есть опыт общения с Python’ом, и вы знаете, как выполнять базовые операции манипуляции данными и рисовать графики. Предлагаемый ниже метод анимации – не единственный, и если вы знаете какой-нибудь другой, вам будет интересно сравнить их друг с другом. Мы будем использовать трехмерные линии и точки для создания траекторий, но эти же методы можно распространить на другие визуализации – например, двухмерные линии, столбчатые и секторные диаграммы, контуры и т. д. Импортируем пакеты В Python’е есть куча библиотек для анализа данных и мы воспользуемся парой из них. Давайте начнем писать новый скрипт и импортируем пакеты, нужные для этого проекта: # Импортируем пакеты import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import animation NumPy используется для создания числовых массивов и вызова тригонометрических функций (сокращается до np для удобства). Pyplot из пакета Matplotlib используется для рисования графиков (сокращается до plt для удобства). Axes3D используется создания трехмерной системы координат в наших графиках. 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. Спасибо за прочтение! *** Материалы по теме Анимация графиков в Python за 4 шага 🎨 Как нарисовать смайлик и квадрат в онлайн-редакторе графики Paint с помощью Selenium 🎞️ Как с помощью Python делать красивые математические анимации
Разработчик ПО (системы PDM/PLM) с 1993 года, компания "ИНТЕРМЕХ" (www.intermech.ru). В 2020-м успешно закончил курсы "Основы Data Science" (минская IT Academy) Референт-переводчик технической литературы с английского языка. Показываем на примерах, как создавать красивые анимации с помощью Python, чтобы удивлять даже самых искушенных зрителей. Если статических графиков недостаточно – нарисуем постоянно меняющиеся анимации! Каждый Data Scientist знает, что важно не только получить данные, решающие некоторую задачу, но и представить эти данные в виде, удобном для восприятия людей, которые будут принимать решения на их основе. Для этого используются диаграммы, гистограммы, графики и многое другое. Но если вы хотите создать презентацию, по-настоящему привлекающую внимание – статических картинок может оказаться недостаточно. Вам потребуются динамические анимации. Когда вы прочитаете эту статью, вы сможете воссоздать график, показанный выше, и использовать полученные знания для создания собственных красивых анимаций. Будем считать, что у вас есть опыт общения с Python’ом, и вы знаете, как выполнять базовые операции манипуляции данными и рисовать графики. Предлагаемый ниже метод анимации – не единственный, и если вы знаете какой-нибудь другой, вам будет интересно сравнить их друг с другом. Мы будем использовать трехмерные линии и точки для создания траекторий, но эти же методы можно распространить на другие визуализации – например, двухмерные линии, столбчатые и секторные диаграммы, контуры и т. д. Импортируем пакеты В Python’е есть куча библиотек для анализа данных и мы воспользуемся парой из них. Давайте начнем писать новый скрипт и импортируем пакеты, нужные для этого проекта: # Импортируем пакеты import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import animation NumPy используется для создания числовых массивов и вызова тригонометрических функций (сокращается до np для удобства). Pyplot из пакета Matplotlib используется для рисования графиков (сокращается до plt для удобства). Axes3D используется создания трехмерной системы координат в наших графиках. 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. Спасибо за прочтение! *** Материалы по теме Анимация графиков в Python за 4 шага 🎨 Как нарисовать смайлик и квадрат в онлайн-редакторе графики Paint с помощью Selenium 🎞️ Как с помощью Python делать красивые математические анимации
Если статических графиков недостаточно – нарисуем постоянно меняющиеся анимации!
Каждый Data Scientist знает, что важно не только получить данные, решающие некоторую задачу, но и представить эти данные в виде, удобном для восприятия людей, которые будут принимать решения на их основе. Для этого используются диаграммы, гистограммы, графики и многое другое. Но если вы хотите создать презентацию, по-настоящему привлекающую внимание – статических картинок может оказаться недостаточно. Вам потребуются динамические анимации.
Когда вы прочитаете эту статью, вы сможете воссоздать график, показанный выше, и использовать полученные знания для создания собственных красивых анимаций.
Будем считать, что у вас есть опыт общения с Python’ом, и вы знаете, как выполнять базовые операции манипуляции данными и рисовать графики. Предлагаемый ниже метод анимации – не единственный, и если вы знаете какой-нибудь другой, вам будет интересно сравнить их друг с другом. Мы будем использовать трехмерные линии и точки для создания траекторий, но эти же методы можно распространить на другие визуализации – например, двухмерные линии, столбчатые и секторные диаграммы, контуры и т. д.
В Python’е есть куча библиотек для анализа данных и мы воспользуемся парой из них. Давайте начнем писать новый скрипт и импортируем пакеты, нужные для этого проекта:
# Импортируем пакеты import numpy as np import matplotlib.pyplot as plt from mpl_toolkits.mplot3d import Axes3D from matplotlib import animation
np
plt
animation
Больше полезных материалов вы найдете на нашем телеграм-канале «Библиотека питониста» Интересно, перейти к каналу
Прежде чем думать о рисовании каких-то графиков, мы должны создать данные, на основе которых мы будем рисовать графики. Для этого я создал кое-какие позиционные данные, полученные с помощью функции синуса и временного массива, содержащего значения от 0 до 20 (я обозначил их как секунды анимации).
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 будут использованы в нашей функции анимации, которую мы сейчас определим.
dataSet
numDataPoints
Для анимации нашей картинки мы используем функцию FuncAnimation из импортированного класса animation. Документацию по обоим можно найти здесь. FuncAnimation требует, чтобы мы создали собственную функцию, обновляющую линии, точки и пр., которую мы назовем animate_func.
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’у, созданному ранее.
num,
num
Первое, что делает эта функция – очищает фигуру. Очистка уничтожает линии, точки, оси с метками и заголовок. Затем функция добавляет обновленную линию траектории (от 0 до num) и локацию точки (на шаге num). В этой фигуре начальная точка остается неизменной, так что вы заметите, что num не показывается, поскольку мы не меняем начальную точку. Затем функция определяет наши неизменные пределы по осям. Вы можете убрать эти пределы, если хотите, чтобы оси изменялись по мере продвижения (то есть, ваши оси станут динамическими).
Наконец, наша функция задает заголовок и метки наших осей. Метки очевидны: это x, y, z, обозначающие декартовы координаты. В качестве небольшой дополнительной функциональности у нас есть динамический заголовок, показывающий текущий номер итерации в повременном массиве, t. Мы показываем эти секунды (с округлением до двух цифр после запятой) и обновляем их на каждой итерации. Заметьте, это не настоящие секунды.
x
y
z
t
Последний шаг – это собственно вывод нашей анимации с помощью FuncAnimation. Начнем с создания объекта фигуры с трехмерными осями. Затем вызываем FuncAnimation, принимающую фигуру, нашу функцию анимации, которую мы только что создали, а также значения interval и frames. Interval – это время задержки между фреймами в миллисекундах, а frames – это просто количество фреймов, которые нужно показать. Два последних аргумента не обязательны, но мне нравится включать их, если я хочу иметь возможность настраивать вид анимация.
interval
frames
Interval
# Рисуем анимацию fig = plt.figure() ax = plt.axes(projection='3d') line_ani = animation.FuncAnimation(fig, animate_func, interval=100, frames=numDataPoints) plt.show()
Вы можете запустить этот код, и если все сделано правильно, ваш график должен выглядеть примерно так (скорость движения точки может быть разной):
Если вы хотите сохранить свою анимацию в файл .gif, можно использовать следующий код, делающий именно это:
.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 секунд времени.
f
fps
PillowWriter
Мы познакомились с пакетами mplot3d и animation, а также научились рисовать анимации графиков и сохранять эти анимации в файлы .gif. Спасибо за прочтение!
mplot3d
***
ΠΠ°Ρ Π°Π΄ΡΠ΅Ρ email Π½Π΅ Π±ΡΠ΄Π΅Ρ ΠΎΠΏΡΠ±Π»ΠΈΠΊΠΎΠ²Π°Π½. ΠΠ±ΡΠ·Π°ΡΠ΅Π»ΡΠ½ΡΠ΅ ΠΏΠΎΠ»Ρ ΠΏΠΎΠΌΠ΅ΡΠ΅Π½Ρ *
Π‘ΠΎΡ ΡΠ°Π½ΠΈΡΡ ΠΌΠΎΡ ΠΈΠΌΡ, email ΠΈ Π°Π΄ΡΠ΅Ρ ΡΠ°ΠΉΡΠ° Π² ΡΡΠΎΠΌ Π±ΡΠ°ΡΠ·Π΅ΡΠ΅ Π΄Π»Ρ ΠΏΠΎΡΠ»Π΅Π΄ΡΡΡΠΈΡ ΠΌΠΎΠΈΡ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠ΅Π².
Δ
ΠΡΠΎΡ ΡΠ°ΠΉΡ ΠΈΡΠΏΠΎΠ»ΡΠ·ΡΠ΅Ρ Akismet Π΄Π»Ρ Π±ΠΎΡΡΠ±Ρ ΡΠΎ ΡΠΏΠ°ΠΌΠΎΠΌ. Π£Π·Π½Π°ΠΉΡΠ΅, ΠΊΠ°ΠΊ ΠΎΠ±ΡΠ°Π±Π°ΡΡΠ²Π°ΡΡΡΡ Π²Π°ΡΠΈ Π΄Π°Π½Π½ΡΠ΅ ΠΊΠΎΠΌΠΌΠ΅Π½ΡΠ°ΡΠΈΠ΅Π².