Улучшите свою презентацию по науке о данных с помощью анимации

Люди говорят, что одна картинка стоит тысячи слов, это означает, что одна анимация стоит больше тысячи слов. Почему? ведь анимация - это серия картинок, не так ли? Мы, люди, всегда более внимательны к наличию визуальных элементов, чтобы объяснить, какое явление происходит в наших данных, но иногда статические изображения не могут полностью объяснить. Здесь анимация объясняет, что происходит.

Нам не всегда нужна анимация, чтобы помочь нам понять наши данные, но такие данные, как данные временных рядов, могут быть лучше всего представлены в форме анимации. Цена акций, количество звонков каждый день, процент зачисления с течением времени - это лишь некоторые из примеров данных временного ряда. Эти данные можно визуализировать с помощью анимации.

В этой статье я хочу представить, как создать простую анимацию с использованием языка программирования Python и различных библиотек, чтобы упростить этот процесс. Сюда входят Matplotlib, Celluloid и Plotly.

Анимация Matplotlib

Matplotlib - это дедушка библиотеки визуализации, основанная на языке программирования MATLAB. Многие из разработанных библиотек визуализации будут основаны на этом модуле, и я почти уверен, что почти каждый, кто начинает свое изучение визуализации, начал бы с этого модуля.

В модуле matplotlib есть API, специально используемый для создания анимации путем предоставления необходимых базовых классов. Есть два класса: FuncAnimation и ArtistAnimation. Здесь я бы представил анимацию, созданную классом FuncAnimation, потому что она самая простая.

Я бы показал, как работает этот класс, на примере приведенной выше анимации курса акций. Для приготовления нам потребуются следующие безделушки:

  • Чтобы сохранить анимацию в вашей системе как mp4 или gif, необходимо установить FFmpeg или ImageMagick.
  • Я получил данные о ценах на акции с помощью модуля yahoo_historical. Установите модуль с помощью pip или conda.

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

import pandas as pd
from yahoo_historical import Fetcher
#Acquire our stock price data. Here I choose to take BBCA.JK stock price (BCA Indonesia Bank) from 1 January 2012 until now with 1 day interval. The data would be automatically imported as Pandas DataFrame object
BBCA = Fetcher('BBCA.JK', [2012,1,1], interval = '1d').getHistorical()
BBCA.head()

Просто чтобы убедиться, что наши данные не содержат значения NaN, мы могли бы быстро проверить.

BBCA.isna().any()

Нет значения NaN, с этими данными мы могли бы предварительно обработать данные. Поскольку мы хотим создать анимацию временного ряда, нам нужно сначала преобразовать данные в объект Datetime.

BBCA['Date'] = pd.to_datetime(BBCA['Date'])

Я хотел бы анимировать цену Adj Close для BBCA.JK сверхурочно, поэтому теперь давайте начнем с анимации, созданной с использованием класса FuncAnimation из matplotlib.

#importing libraries
import matplotlib.pyplot as plt
import matplotlib.animation as animation
#Set the figure for the animation framework
fig = plt.figure(figsize = (10,6))
#creating a subplot 
ax1 = fig.add_subplot(1,1,1)
#Preparing empty list as we want to animate the graph one data at a time rather than all at once
date = []
adjclose = []
#Using FuncAnimation we need to create an animation function which return and/or done a repetitive action
def animate(i):
    #Append the empty list with the data located at the index i
    date.append(BBCA['Date'].loc[i])
    adjclose.append(BBCA['Adj Close'].loc[i])
    #Clear the subplot each time the animate is called
    ax1.clear()
    
    ax1.plot(date, adjclose)
    ax1.tick_params(axis = 'x', labelrotation = 90)
    
    ax1.set_xlabel('Date')
    ax1.set_ylabel('Price')
    ax1.set_title('BBCA Stock graph with matplotlib')

ani = animation.FuncAnimation(fig = fig, func = animate, frames = len(BBCA), interval = 20) 
plt.show()

Здесь я бы подробно объяснил параметр FuncAnimation. Важными параметрами здесь являются:

  • Параметр fig в качестве основы для анимации
  • Параметр func для функции анимации, вызываемой для каждого кадра
  • Параметр frames - это источник данных для передачи в параметр func и каждый кадр анимации. Если предоставлено int, это будет эквивалентно функции range (int).
  • Параметр interval контролирует интервал между каждым кадром в миллисекундах.

Чтобы сохранить анимацию в mp4 или gif, просто запустите следующий код.

#You could decide wheteher it is gif or mp4 by change the extension name
ani.save('bbca_stock.gif', writer='imagemagick')

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

from matplotlib import rc
rc('animation', html='html5')
ani

Вот так простая анимация создается с помощью модуля matplotlib. В следующем разделе я представлю другие модули, упрощающие процесс создания анимации.

Целлулоид

Celluloid - модуль, упрощающий процесс создания анимации в matplotlib. Мы используем только фигуру из matplotlib и оттуда создаем класс Camera, чтобы сделать снимок каждой фигуры как кадра. Анимация создается из серии кадров.

Мы попытаемся создать простую анимацию курса акций с использованием целлулоида, как в примере выше. Для подготовки нам нужно сначала установить целлулоид.

pip install celluloid

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

#Importing Camera class from Celluloid module
from celluloid import Camera
#Set the BBCA date as index to simplify the plotting procrss 
test = BBCA.set_index('Date')
#Create the figure for animation creation
fig = plt.figure(figsize = (10,6))
#Create camera object by inputting the figure object
camera = Camera(fig)
#Looping the plotting process and taking a snapshot for each frame. I set the loop to take 50 data each time to had a faster interval.
for i in range(49,len(BBCA),50):
    test['Adj Close'][0:i].plot(color = 'blue')
    plt.xlabel('Date')
    plt.ylabel('Price')
    plt.title('BBCA Stock graph with Celluloid')
    #Snap the figure in each loop process
    camera.snap()
    
#Create the animation    
animation = camera.animate()
animation.save('bbca_stock_celluloid.gif', writer='imagemagick')

Сюжетно

Plotly - это модуль визуализации, который может похвастаться ведущим интерфейсом для машинного обучения и моделей науки о данных. От статического графика, интерактивной визуализации до аналитической панели инструментов; Сюжетно предлагает все это. Анимация также включена в модуль Plotly с помощью всего нескольких строк кода.

Первым делом нам нужно установить модуль plotly.

pip install plotly

В модуле plotly есть множество функций, но в нашем случае прямо сейчас мы будем использовать plotly express, чтобы быстро создать график. Мы также будем использовать данные о населении, доступные из модуля plotly.

import plotly.express as px
df = px.data.gapminder()
df.head()

Наши данные будут выглядеть так. У нас есть коллекция стран с 5-летним перерывом каждый раз, и различные столбцы показывают состояние своей страны. Попробуем создать быструю анимацию, используя сюжетно из этих данных.

#Creating animation using plotly express
fig = px.scatter(df, x="gdpPercap", y="lifeExp", animation_frame="year", animation_group="country",
           size="pop", color="continent", hover_name="country",
           log_x=True, size_max=55, range_x=[100,100000], range_y=[25,90])
fig.show()

Вот некоторые параметры, которые следует запомнить в приведенном выше коде:

  • animation_frame контролирует ход анимации. Мы сортируем это значение сначала от самого раннего к последнему (или наоборот, если хотите).
  • animation_group используется для обеспечения постоянства объекта во всех кадрах анимации: строки с совпадающими `animation_group`s 'будут обрабатываться так, как если бы они описывали один и тот же объект в каждом кадре.

Вот результат анимации на моем Jupyter Notebook.

Одна из слабых сторон сюжета заключается в том, что мы не могли экспортировать анимацию в нашу систему (мы могли экспортировать статическое изображение, но не анимацию). Итак, мы используем процесс анимации только тогда, когда используем Jupyter Notebook или интегрировали его в нашу панель управления Plotly. Как мы видим, код привел к интерактивному сюжету, на котором мы могли воспроизвести анимацию (при желании мы также могли зависать в нашем сюжете).

Почти весь сюжет, созданный с помощью plotly express, обеспечивает возможность создания анимации, поэтому он не ограничивается только диаграммой рассеяния. Обратитесь к документации, если хотите узнать весь сюжет.

Заключение

Здесь я показал вам простой способ представить ваши данные с помощью анимации и несколько модулей, которые помогут процессу; в том числе Matplotlib, Celluloid и Plotly. Имея за собой всего несколько строк кода и логику, мы могли бы улучшить нашу презентацию красивой анимацией.

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

Если вы не подписаны как Средний участник, рассмотрите возможность подписки через мой реферал.