Как и почему я использовал Plotly (вместо D3) для визуализации моих данных Lollapalooza

1656625094 kak i pochemu ya ispolzoval plotly vmesto d3 dlya vizualizaczii

Дебора Мескита

AAZJkghrhPsz5rTI0pH0HqHYP5zQexiVBGuW
Lollapalooza Brasil 2018 — Уэсли Аллен — IHateFlash

D3.js – это отличная библиотека JavaScript, но она имеет очень стремительный процесс обучения. Это делает задачку сотворения ценной визуализации чем-то, что просит много усилий. Эти дополнительные усилия подходят, если ваша цель создать новые и креативные визуализации данных, но часто это не так.

Часто ваша цель может быть просто построить интерактивную визуализацию с некоторыми хорошо известными диаграммами. И если вы не инженер по интерфейсу, это может стать немного сложным.

Как ученые данных, одна из наших основных задач – манипулирование данными. Сегодня основным инструментом, который я использую для этого, Pandas (Python). А если я вам это скажу ты может создавать красивые и интерактивные диаграммы для Интернета прямо из ваших кадров данных Pandas? Ну, ты можешь! Мы можем использовать Сюжетно для того.

Для записи, есть библиотеки API Plotly для Matlab, R и JavaScript, но здесь мы будем придерживаться библиотеки Python.

Справедливости ради Plotly построен на основе d3.js (и stack.gl). Основное отличие между D3 и Plotly состоит в том, что это именно Plotly. библиотека графиков.

Давайте построим гистограмму, чтобы узнать, как работает Plotly.

Построение гистограммы с сюжетом

В философии Плотли есть 3 основные концепции:

Данные

Объект Data определяет, что мы хотим отразить на диаграмме (т.е. данные). Мы определяем набор данных и спецификации для отображения их в виде след. Объект данных может иметь много следов. Подумайте о линейной диаграмме с двумя линиями, представляющими две разные категории: каждая линия является следом.

Макет

Объект Layout определяет объекты, не связанные с данными (например, заголовок, названия осей и т.п.). Мы также можем использовать макет для добавления инструкций и фигур в диаграмму.

рисунок

Объект Figure создает конечный объект, который необходимо выстроить. Это объект, содержащий как данные, так и макет.

Визуализации Plotly создаются с помощью plotly.js. Это означает, что API Python справедливо пакет для взаимодействия с библиотекой plotly.js. The plotly.graph_objs модуль содержит функции, которые будут создавать для нас объекты графика.

Ладно, теперь мы готовы построить гистограмму:

import plotly.graph_objs as goimport pandas as pdimport plotly.offline as offline
df = pd.read_csv("data.csv")
df_purchases_by_type = df.pivot_table(    index = "place",     columns = "date",     values = "price",     aggfunc = "sum"    ).fillna(0)
trace_microbar = go.Bar(    x = df_purchases_by_type.columns,     y = df_purchases_by_type.loc["MICROBAR"])
data = [trace_microbar]
layout = go.Layout(title = "Purchases by place", showlegend = True)
figure = go.Figure(data = data, layout = layout)
offline.plot(figure)

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

Ладно, сначала мы хотим показать полосы одной категории (место под названием "MICROBAR"). Поэтому мы создаем объект данных (список) с помощью go.Bar() (след), что указывает данные для осей x и y. Trace – это словарь, а данные – это список словарей. Вот trace_microbar содержимое (обратите внимание на ключ типа):

{'type': 'bar',  'x': Index(['23/03/2018', '24/03/2018', '25/03/2018'], dtype="object", name="date"),   'y': date  23/03/2018     0.0  24/03/2018     0.0  25/03/2018    56.0  Name: MICROBAR, dtype: float64}

В объекте Layout мы устанавливаем название диаграммы и параметр showlegend. Затем мы заворачиваем данные и макет в фигуру и вызываем plotly.offline.plot() для отображения диаграммы. Plotly имеет разные варианты отображения диаграмм, но давайте останемся на оффлайновом варианте. Это откроет окно обозревателя с нашей диаграммой.

UpBNLA8zEIXNHLy8j4Y10cbLP2piXXmZ2bhm
Результат

Я хочу показать все в столбчатой ​​диаграмме с накоплением, поэтому мы создадим список данных со всеми следами (местами), которые мы хотим отразить, и установим barmode параметр до стек.

import plotly.graph_objs as goimport pandas as pdimport plotly.offline as offline
df = pd.read_csv("data.csv")
df_purchases_by_place = df.pivot_table(index="place",columns="date",values="price",aggfunc="sum").fillna(0)
data = []
for index,place in df_purchases_by_place.iterrows():    trace = go.Bar(        x = df_purchases_by_place.columns,         y = place, name=index    )    data.append(trace)
layout = go.Layout(          title="Purchases by place",           showlegend=True,           barmode="stack"        )
figure = go.Figure(data=data, layout=layout)
offline.plot(figure)
sXdlsRvCRWAfr8ve73JM2bYX7YjswDXO0xTV
Гистограмма с накоплением

И это основы Plotly. Чтобы настроить наши диаграммы, мы устанавливаем разные параметры для трасс и макета. Теперь давайте поговорим о визуализации Lollapalooza.

Мой опыт Lollapalooza

Для издания Lollapalooza Brazil 2018 все покупки были сделаны через браслет с поддержкой RFID. Они отправляют данные на ваш адрес электронной почты, поэтому я решил взглянуть на это. Что мы можем узнать обо мне и моем опыте, анализируя покупки, которые я сделал на фестивале?

Вот как выглядят данные:

  • Дата покупки
  • час покупки
  • продукт
  • количество
  • этап
  • место, где я совершил покупку

На основе этих данных ответим на некоторые вопросы.

Куда я был на фестивале?

Данные говорят только о названии места, где я совершил покупку, а фестиваль проходил на Автодромо де Интерлагос. Я взял карту с этапами отсюда и воспользовался инструментом georeference из georeference.com, чтобы получить координаты широты и долготы для этапов.

2oYtS8TBUrEtk2pmtTvgV6nI05yfAtqMxJmZ
Карта Lollapalooza Бразилия 2018 года

Нам нужно отобразить карту и маркеры для каждой покупки, поэтому мы будем использовать Mapbox и scattermapbox след. Сначала рассмотрим только этапы, чтобы увидеть, как это работает:

import plotly.graph_objs as goimport plotly.offline as offlineimport pandas as pd
mapbox_token = "" #https://www.mapbox.com/help/define-access-token/
df = pd.read_csv("stages.csv")
trace = go.Scattermapbox(    lat = df["latitude"],     lon = df["longitude"],     text=df["stage"],     marker=go.Marker(size=10),     mode="markers+text",     textposition="top"  )
data = [trace]
layout = go.Layout(          mapbox=dict(            accesstoken=mapbox_token,             center=dict(              lat = -23.701057,              lon = -46.6970635             ),             zoom=14.5          )         )
figure = go.Figure(data = data, layout = layout)
offline.plot(figure)
4ermT5RH5imnzvnjqNQ7lLSeF8Gyz70VtWWq
Наша первая карта

Давайте узнаем новый параметр макета: updatemenus. Мы будем использовать это для отображения маркеров по дате. Есть четыре возможных способа обновления:

  • "restyle": изменять данные или атрибуты данных
  • "relayout": изменить атрибуты макета
  • "update": изменить данные и атрибуты макета
  • "animate": начать или приостановить анимацию)

Чтобы обновить маркеры, нам нужно только изменить данные, поэтому мы будем использовать "restyle" метод. Во время рестайлинга можно установить изменения для каждой трассы или для всех трасс. Здесь мы устанавливаем, чтобы каждая трасса была видима только тогда, когда пользователь изменяет параметр раскрывающегося меню:

import plotly.graph_objs as goimport plotly.offline as offlineimport pandas as pdimport numpy as np
mapbox_token = ""
df = pd.read_csv("data.csv")
df_markers = df.groupby(["latitude","longitude","date"]).agg(dict(product = lambda x: "%s" % ", ".join(x), hour = lambda x: "%s" % ", ".join(x)))df_markers.reset_index(inplace=True)
data = []update_buttons = []
dates = np.unique(df_markers["date"])
for i,date in enumerate(dates):    df_markers_date = df_markers[df_markers["date"] == date]    trace = go.Scattermapbox(               lat = df_markers_date["latitude"],               lon = df_markers_date["longitude"],               name = date, text=df_markers_date["product"]+"<br>"+df_markers_date["hour"],               visible=False            )    data.append(trace)    
    visible_traces = np.full(len(dates), False)    visible_traces[i] = True
    button = dict(               label=date,                method="restyle",                args=[dict(visible = visible_traces)]             )    update_buttons.append(button)
updatemenus = [dict(active=-1, buttons = update_buttons)]
layout = go.Layout(            mapbox=dict(              accesstoken=mapbox_token,               center=dict(                  lat = -23.701057,                  lon = -46.6970635),                   zoom=14.5),               updatemenus=updatemenus           )
figure = go.Figure(data = data, layout = layout)
offline.plot(figure)
EJFQgSo-90XJEj4dO2sLW6nkOsvrAQBjqpmC
Карта с дропбоксом

Как я потратил свои деньги?

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

import plotly.graph_objs as goimport pandas as pdimport plotly.offline as offline
df = pd.read_csv("data.csv")
df_purchases_by_type = df.pivot_table(index="place",columns="date",values="price",aggfunc="sum").fillna(0)df["hour_int"] = pd.to_datetime(df["hour"], format="%H:%M", errors="coerce").apply(lambda x: int(x.hour))
df_heatmap = df.pivot_table(index="date",values="price",columns="hour", aggfunc="sum").fillna(0)
trace_heatmap = go.Heatmap(                 x = df_heatmap.columns,                  y = df_heatmap.index,                  z = [df_heatmap.iloc[0], df_heatmap.iloc[1], df_heatmap.iloc[2]]                )
data = [trace_heatmap]
layout = go.Layout(title="Purchases by place", showlegend=True)
figure = go.Figure(data=data, layout=layout)
offline.plot(figure)
G7TnpLRmkUsTxI4HbpPzePIiU7QFcNDip2tX
Когда я трачу свои деньги (нам нужно изменить эту цветовую шкалу, ха-ха)

Какие концерты я смотрел?

Теперь перейдем к самому крутому: могу ли я угадать концерты, которые я посетил, только за своими покупками?

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

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

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

import plotly.graph_objs as goimport plotly.offline as offlineimport pandas as pd
df_table = pd.read_csv("concerts_I_attended.csv")
def colorFont(x):    if x == "Yes":       return "rgb(0,0,9)"    else:       return "rgb(178,178,178)"
df_table["color"] = df_table["correct"].apply(lambda x: colorFont(x))
trace_table = go.Table(      header=dict(          values=["Concert","Date","Correct?"],          fill=dict(            color=("rgb(82,187,47)"))          ),          cells=dict(          values= [df_table.concert,df_table.date,df_table.correct],          font=dict(color=([df_table.color])))      )
data = [trace_table]
figure = go.Figure(data = data)
offline.plot(figure)
5hBhtw5LGupq5nBxUhBCpX27w4cS6JNB0ziW
Как выглядит стол

Три концерта отсутствовали, а четыре были неправильными, что дает нам точность 67% и отзыв 72%.

Объединив все вместе: тире

У нас есть все диаграммы, но цель – собрать их все вместе на странице. Для этого мы будем использовать Dash (от Plotly).

«Dash – это фреймворк Python для создания аналитических веб-приложений. JavaScript не требуется. Dash идеально подходит для создания приложений для визуализации данных с пользовательскими интерфейсами на чистом Python. Он особенно подходит для тех, кто работает с данными на Python». — Сайт Plotly

Dash пишется поверх Flask, Plotly.js и React.js. Это работает очень похоже на то, как мы создаем диаграммы Plotly:

import dashimport dash_core_components as dccimport dash_html_components as htmlimport plotly.graph_objs as goimport pandas as pd app = dash.Dash()
df_table = pd.read_csv("concerts_I_attended.csv").dropna(subset=["concert"])def colorFont(x):    if x == "Yes":       return "rgb(0,0,9)"    else:       return "rgb(178,178,178)"
df_table["color"] = df_table["correct"].apply(lambda x: colorFont(x))
trace_table = go.Table(header=dict(values=["Concert","Date","Correct?"],fill=dict(color=("rgb(82,187,47)"))),cells=dict(values=[df_table.concert,df_table.date,df_table.correct],font=dict(color=([df_table.color]))))
data_table = [trace_table]
app.layout = html.Div(children=[    html.Div(        [            dcc.Markdown(                """                ## My experience at Lollapalooza Brazil 2018                ***                """.replace('  ', ''),                className="eight columns offset-by-two"            )        ],        className="row",        style=dict(textAlign="center",marginBottom="15px")    ),
html.Div([        html.Div([            html.H5('Which concerts did I attend?', style=dict(textAlign="center")),            html.Div('People usually buy things before or after a concert, so I took the list of concerts, got the distances from the location of the purchases to the stages and tried to guess which concerts did I attend. 8 concerts were correct and 3 were missing from a total of 12 concerts.', style=dict(textAlign="center")),            dcc.Graph(id='table', figure=go.Figure(data=data_table,layout=go.Layout(margin=dict(t=30)))),        ], className="twelve columns"),    ], className="row")])
app.css.append_css({    'external_url': 'https://codepen.io/chriddyp/pen/bWLwgP.css'})
if __name__ == '__main__':    app.run_server(debug=True)
FMIYSv4Jj3oBsqjRu-jM9G9bS2Bt74XlnWik
Объединив все это вместе с помощью тире!

Круто, верно?

Я провел здесь окончательную визуализацию и весь код здесь.

Есть несколько альтернатив для размещения визуализаций: Dash имеет общедоступный хостинг приложений dash, а Plotly также предоставляет веб-сервис для размещения графиков.

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

У меня был достаточно хороший опыт работы с Plotly, я обязательно использую его для своего следующего проекта. Что вы думаете об этом после этого обзора? А какие инструменты вы используете для создания визуализаций для Интернета? Поделитесь ими в комментариях! И спасибо, что читаете! ?

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *