de Déborah Mesquita

Cum și de ce am folosit Plotly (în loc de D3) pentru a vizualiza datele mele Lollapalooza

Cum si de ce am folosit Plotly in loc de
Lollapalooza Brasil 2018 – Wesley Allen – IHateFlash

D3.js este o bibliotecă JavaScript minunată, dar are o curbă de învățare foarte abruptă. Acest lucru face ca sarcina de a construi o vizualizare valoroasă să fie ceva ce poate necesita mult efort. Acest efort suplimentar este ok dacă obiectivul dvs. este să realizați vizualizări de date noi și creative, dar deseori nu este cazul.

De multe ori, scopul tău ar putea fi doar pentru a construi o vizualizare interactivă cu câteva diagrame bine cunoscute. Și dacă nu sunteți inginer front-end, acest lucru poate deveni puțin dificil.

Ca oameni de știință a datelor, una dintre sarcinile noastre principale este manipularea datelor. Astăzi, principalul instrument pe care îl folosesc pentru asta este Panda (Piton). Dacă îți spun asta tu poate construi câteva diagrame frumoase și interactive pentru web chiar din cadrele de date Pandas? Bine, poti! Putem folosi Complot pentru asta.

Pentru înregistrare, există și biblioteci API Plotly pentru Matlab, R și JavaScript, dar vom rămâne aici cu biblioteca Python.

ad-banner

Pentru a fi corect, Plotly este construit în partea de sus a d3.js (și stack.gl). Principala diferență între D3 și Plotly este că Plotly este specific o bibliotecă de diagrame.

Să construim o diagramă cu bare pentru a afla cum funcționează complot.

Construirea unui grafic de bare cu complot

Există 3 concepte principale în filosofia lui Plotly:

  • Date
  • Aspect
  • Figura

Date

Obiectul Data definește ceea ce vrem să afișăm în diagramă (adică datele). Definim o colecție de date și specificațiile pentru a le afișa ca urmă. Un obiect de date poate avea multe urme. Gândiți-vă la o diagramă liniară cu două linii reprezentând două categorii diferite: fiecare linie este o urmă.

Aspect

Obiectul Layout definește caracteristici care nu sunt legate de date (cum ar fi titlul, titlurile axelor și așa mai departe). De asemenea, putem utiliza aspectul pentru a adăuga adnotări și forme în diagramă.

Figura

Obiectul Figura creează obiectul final de trasat. Este un obiect care conține atât date, cât și aspect.

Vizualizările grafice sunt construite cu plotly.js. Aceasta înseamnă că API-ul Python este corect un pachet pentru a interacționa cu biblioteca plotly.js. plotly.graph_objs modulul conține funcțiile care vor genera obiecte grafice pentru noi.

Ok, acum suntem pregătiți să construim un grafic cu bare:

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)

Notă: în acest articol nu vom vorbi despre ceea ce fac cu cadrele de date. Dar dacă doriți o postare despre asta, anunțați-mă în comentarii?

Bine, așa că mai întâi vrem să arătăm barele unei categorii (un loc numit "MICROBAR"). Deci creăm un obiect de date (o listă) cu go.Bar() (o urmă) specificând datele pentru axele x și y. Trace este un dicționar, iar datele sunt o listă de dicționare. Aici este trace_microbar conținut (observați cheia tip):

{'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}

În obiectul Layout, setăm titlul diagramei și parametrul showlegend. Apoi, înfășurăm datele și aspectul într-o figură și apelăm plotly.offline.plot() pentru a afișa graficul. Plotly are diferite opțiuni pentru afișarea diagramelor, dar să rămânem cu opțiunea offline aici. Aceasta va deschide o fereastră de browser cu graficul nostru.

Cum si de ce am folosit Plotly in loc de
Rezultatul

Vreau să afișez totul într-o diagramă de bare stivuite, așa că vom crea o listă de date cu toate urmele (locurile) pe care dorim să le afișăm și să setăm barmode parametru pentru grămadă.

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)
1612192808 901 Cum si de ce am folosit Plotly in loc de
Grafic de bare stivuite

Și acesta este elementele de bază ale lui Plotly. Pentru a ne personaliza graficele, stabilim parametri diferiți pentru urme și aspect. Acum să mergem mai departe și să vorbim despre vizualizarea Lollapalooza.

Experiența mea Lollapalooza

Pentru ediția 2018 a Lollapalooza Brazilia, toate achizițiile au fost făcute printr-o brățară cu funcție RFID. Ei trimit datele la adresa dvs. de e-mail, așa că am decis să mă uit la ele. Ce putem învăța despre mine și experiența mea analizând achizițiile pe care le-am făcut la festival?

Așa arată datele:

  • Data cumpărării
  • ora de cumpărare
  • produs
  • cantitate
  • etapă
  • locul unde am făcut achiziția

Pe baza acestor date, să răspundem la câteva întrebări.

Unde m-am dus în timpul festivalului?

Datele ne spun doar numele locației în care am făcut achiziția, iar festivalul a avut loc la Autódromo de Interlagos. Am luat harta cu etapele din Aici și a folosit instrumentul georeferențiator de la georeference.com pentru a obține coordonatele de latitudine și longitudine pentru etape.

1612192808 274 Cum si de ce am folosit Plotly in loc de
Harta Lollapalooza Brazilia 2018

Trebuie să afișăm o hartă și marcajele pentru fiecare achiziție, așa că vom folosi Mapbox si scattermapbox urmă. Mai întâi să trasăm doar etapele pentru a vedea cum funcționează:

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)
1612192808 232 Cum si de ce am folosit Plotly in loc de
Prima noastră hartă

Să învățăm un nou parametru Layout: updatemenus. Vom folosi acest lucru pentru a afișa marcajele după dată. Există patru posibile metode de actualizare:

  • "restyle": modificați datele sau atributele de date
  • "relayout": modifica atributele de aspect
  • "update": modificați datele și atribute de aspect
  • "animate": porniți sau întrerupeți un animaţie)

Pentru a actualiza markerii, trebuie doar să modificăm datele, așa că vom folosi fișierul "restyle" metodă. La restilizare puteți seta modificările pentru fiecare urmă sau pentru toate urmele. Aici setăm fiecare urmă să fie vizibilă numai atunci când utilizatorul modifică opțiunea din meniul derulant:

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)
1612192809 485 Cum si de ce am folosit Plotly in loc de
O hartă cu un dropbox

Cum mi-am cheltuit banii?

Pentru a răspunde la asta, am creat o diagramă cu bare cu cheltuielile mele pentru mâncare și băuturi până în fiecare zi și am construit o hartă de căldură pentru a arăta când am cumpărat lucruri. Am văzut deja cum să construim un grafic cu bare, așa că acum să construim un grafic cu hărți termice:

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)
1612192809 207 Cum si de ce am folosit Plotly in loc de
Când îmi cheltuiesc banii (va trebui să schimbăm această scală de culori haha)

Ce concerte am urmărit?

Acum să mergem la cea mai tare parte: aș putea ghici concertele la care am participat numai pe baza achizițiilor mele?

În mod ideal, atunci când urmărim un spectacol, noi sunt vizionarea spectacolului (și nu cumpărarea de lucruri), deci achizițiile ar trebui făcute inainte de sau după fiecare concert. Apoi am făcut o listă a fiecărui concert care a avut loc cu o oră înainte, cu o oră după și în funcție de ora la care s-a făcut achiziția.

Pentru a afla la care dintre aceste spectacole am participat, am calculat distanța de la locația achiziției la fiecare etapă. Spectacolele la care am participat ar trebui să fie cele cu cea mai mică distanță de concesii.

Deoarece dorim să arătăm fiecare punct de date, cea mai bună alegere pentru o vizualizare este un tabel. Să construim unul:

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)
1612192809 322 Cum si de ce am folosit Plotly in loc de
Cum arată masa

Au lipsit trei concerte și patru au fost incorecte, oferindu-ne o precizie de 67% și o rechemare de 72%.

Punând totul împreună: liniuță

Avem toate graficele, dar scopul este să le punem pe toate pe o pagină. Pentru a face asta vom folosi Dash (de Plotly).

„Dash este un cadru Python pentru crearea de aplicații web analitice. Nu este necesar JavaScript. Dash este ideal pentru construirea de aplicații de vizualizare a datelor cu interfețe de utilizator foarte personalizate în Python pur. Este potrivit în special pentru oricine lucrează cu date în Python. ” – Site-ul lui Plotly

Dash este scris deasupra Flask, Plotly.js și React.js. Funcționează într-un mod foarte asemănător cu modul în care creăm diagrame 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)
1612192809 433 Cum si de ce am folosit Plotly in loc de
Punând totul împreună cu liniuță!

Cool nu?

Am găzduit vizualizarea finală Aici si tot codul este aici.

Există câteva alternative la găzduirea vizualizărilor: Dash are o găzduire publică a aplicației dash și Plotly oferă și un serviciu web pentru găzduirea graficelor.

Ați găsit util acest articol? Încerc tot posibilul să scriu în fiecare lună un articol de scufundare profundă, poți primesc un e-mail când public unul nou.

Am avut o experiență destul de bună cu Plotly, cu siguranță o voi folosi pentru următorul meu proiect. Ce părere aveți despre aceasta după această prezentare generală? Și ce alte instrumente folosiți pentru a construi vizualizări pentru web? Distribuiți-le în comentarii! Și vă mulțumesc că ați citit! ?