Найти тему
Nuances of programming

Создание анимированных диаграмм в Python

Оглавление

Источник: Nuances of Programming

-2

В ситуации постоянного и необычайного роста объема данных нам не обойтись без аналитиков, в задачи которых входят их анализ и интерпретация. После обработки данных необходимо эффективно сообщить о полученных результатах.

Однако это может оказаться довольно сложной задачей. Для успешной коммуникации, основанной на данных, используется популярная и мощная техника сторителлинга (рассказывания историй).

“Факт, что в нашем распоряжении находится вся информация в мире, совсем не облегчает процесс коммуникации, а, наоборот, усложняет его”. (Коул Нуссбаумер Кнафлич, автор книги “Storytelling with Data”)

Визуализация данных имеет большое значение для сторителлинга и коммуникации. Анимированная визуализация способствует более выразительному отображению данных и всегда вызывает положительный эмоциональный отклик.

В этой статье вы узнаете о том, как создавать анимированные диаграммы и добавлять новое измерение в гистограммы, линейные и круговые диаграммы. Эта статья — лишь первый шаг в мир безграничных возможностей.

Двойной маятник
Двойной маятник

Как работает анимация

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

Этот пакет является методом расширения FuncAnimation и частью класса Animation библиотеки Matplotlib в Python. Мы рассмотрим разнообразные примеры использования упомянутого интерфейса, но пока будем считать эту функцию циклом while, который продолжает перерисовывать нашу фигуру на холсте.

Как использовать библиотеку

Я смог лучше понять процесс создания анимированных диаграмм, начав их изучение с конца. Магия анимации начинается с двух следующих строк:

import matplotlib.animation as ani

animator = ani.FuncAnimation(fig, chartfunc, interval = 100)

Посмотрим на эти вводные данные FuncAnimation:

  1. fig обозначает объект рисунка, на котором мы будем “рисовать диаграмму”.
  2. chartfunc — это функция, которая принимает числовой ввод, показывающий время измерения во временном ряду (по мере увеличения числа мы продвигаемся по временной шкале).
  3. interval — это задержка между кадрами в миллисекундах (по умолчанию до 200).

Ознакомьтесь с документацией по дополнительным параметрам входных данных.

В дальнейшем остается только параметризовать диаграммы в функцию, принимающую в виде числового ввода точку во временном ряду, и процесс запущен!

Как начать работу

Проверим на практике, как хорошо мы усвоили основы. Для этого создадим диаграммы, используя статистические данные по пандемии COVID-19 (число смертей в день) и готовый набор данных из приведенного ниже кода.

import matplotlib.animation as ani
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

url = 'https://raw.githubusercontent.com/CSSEGISandData/COVID-19/master/csse_covid_19_data/csse_covid_19_time_series
/time_series_covid19_deaths_global.csv'
df = pd.read_csv(url, delimiter=',', header='infer')

df_interest = df.loc[
df['Country/Region'].isin(['United Kingdom', 'US', 'Italy', 'Germany'])
& df['Province/State'].isna()]

df_interest.rename(
index=lambda x: df_interest.at[x, 'Country/Region'], inplace=True)
df1 = df_interest.transpose()

df1 = df1.drop(['Province/State', 'Country/Region', 'Lat', 'Long'])
df1 = df1.loc[(df1 != 0).any(1)]
df1.index = pd.to_datetime(df1.index)

-4

Анимированная линейная диаграмма

-5

Сначала определим параметры диаграммы, которые останутся постоянными. То есть создадим объект рисунка, координаты x и y, а также установим цвета линий и поля этого объекта.

import numpy as np
import matplotlib.pyplot as plt

color = ['red', 'green', 'blue', 'orange']
fig = plt.figure()
plt.xticks(rotation=45, ha="right", rotation_mode="anchor") #циклическое перемещение значений по оси x
plt.subplots_adjust(bottom = 0.2, top = 0.9) #убеждаемся, что даты (по оси x) умещаются на экране
plt.ylabel('No of Deaths')
plt.xlabel('Dates')

Затем нужно настроить функцию кривой и анимировать ее:

def buildmebarchart(i=int):
plt.legend(df1.columns)
p = plt.plot(df1[:i].index, df1[:i].values) #обращаем внимание, что происходит возврат набора данных вплоть до точки i
for i in range(0,4):
p[i].set_color(color[i]) #устанавливаем цвет для каждой кривой

importmatplotlib.animation as ani
animator = ani.FuncAnimation(fig, buildmebarchart, interval = 100)
plt.show()

Анимированная круговая диаграмма

-6

Структуры кода круговой и линейной диаграммы похожи, но есть и некоторые отличия.

import numpy as np
import matplotlib.pyplot as plt

fig,ax = plt.subplots()
explode=[0.01,0.01,0.01,0.01] #выделяем каждый сектор круга

def getmepie(i):
def absolute_value(val): #превращаем % обратно в число
a = np.round(val/100.*df1.head(i).max().sum(), 0)
return int(a)
ax.clear()
plot = df1.head(i).max().plot.pie(y=df1.columns,autopct=absolute_value, label='',explode = explode, shadow = True)
plot.set_title('Total Number of Deaths\n' + str(df1.index[min(i,
len(df1.index)-1 )].strftime('%y-%m-%d')), fontsize=12)
import matplotlib.animation as ani
animator = ani.FuncAnimation(fig, getmepie, interval = 200)
plt.show()

Главное отличие состоит в том, что в выше приведенном коде каждый раз возвращается один набор значений. А в линейном графике мы возвращали весь временной ряд к точке, с которого начинали. Для этого использовалась:

df1.head(i).max()

df1.head(i) возвращает временной ряд, но .max() гарантирует, что мы получаем только самые последние данные (потому что общее значение смертей либо останется таким же, либо будет расти).

Анимированная гистограмма

-7

Создание гистограммы такой же простой процесс, как и ранее рассмотренные примеры. В данном случае я включил и горизонтальную, и вертикальную гистограммы. В зависимости от того, какую гистограмму вы хотите создать, вам нужно определить переменную bar.

fig = plt.figure()
bar = ''

def buildmebarchart(i=int):
iv = min(i, len(df1.index)-1) #Цикл производит одну дополнительную итерацию, что приводит к выходу структур данных из границ. Это был самый простой (точнее, самый ленивый)способ решить проблему :)
objects = df1.max().index
y_pos = np.arange(len(objects))
performance = df1.iloc[[iv]].values.tolist()[0]
if bar == 'vertical':
plt.bar(y_pos, performance, align='center', color=['red', 'green', 'blue', 'orange'])
plt.xticks(y_pos, objects)
plt.ylabel('Deaths')
plt.xlabel('Countries')
plt.title('Deaths per Country \n' + str(df1.index[iv].strftime('%y-%m-%d')))
else:
plt.barh(y_pos, performance, align='center', color=['red', 'green', 'blue', 'orange'])
plt.yticks(y_pos, objects)
plt.xlabel('Deaths')
plt.ylabel('Countries')

animator = ani.FuncAnimation(fig, buildmebarchart, interval=100)

plt.show()

Как сохранить анимированные диаграммы

Создав свои первые анимированные диаграммы, вы, конечно же, захотите ими поделиться. Как же их сохранить?

К счастью, для этого необходима всего одна строка кода:

animator.save(r'C:\temp\myfirstAnimation.gif')

С более подробной информацией можно ознакомиться здесь.

Читайте также:

Читайте нас в Telegram, VK

Перевод статьи Costas Andreou: Learn How to Create Animated Graphs in Python