Plotly: come specificare elementi dell'asse x categoriali in un'animazione espressa in modo grafico?

Aug 22 2020

Ho i seguenti dati.

Sto usando un cursore, in modo da poter scorrere le diverse date (guarda l'immagine sotto per vedere cosa è un cursore nel caso).

Ora, poiché la mia categoria può cambiare tra le date, voglio inizializzare il mio intervallo dell'asse x con A, B, C, E, F, indipendentemente dalla mia data. Quindi a volte non avrò punti dati in una categoria, ma questo non mi importa.

Quindi come posso inizializzare il mio intervallo dell'asse x e fare in modo che i miei punti dati si adattino all'asse x inizializzato?

Sto usando python3 e plotly express.

Questo è il mio codice per ora:

data.columns = ['price', 'category', 'date']
    data = data.sort_values(by=['date', 'price'])
    fig = px.scatter(data, x = "category", y = "price", animation_frame="date")
    fig.update_layout(
        yaxis_title="Price (€)",
    )
    fig['layout']['updatemenus'][0]['pad']['t'] = 180
    fig['layout']['sliders'][0]['pad']['t'] = 200
    fig.write_html("/home/**/Desktop/1.html", auto_play=True)

Spero di essere stato abbastanza chiaro. Per favore fatemi sapere se avete bisogno di ulteriori informazioni. Qualsiasi idea o suggerimento è il benvenuto :)

Risposte

vestland Aug 23 2020 at 22:56

La risposta:

L'unico modo per assicurarti che tutte le categorie siano rappresentate sull'asse x per tutti i fotogrammi dell'animazione è assicurarti che appaiano nel primo Date = X. Quindi non puoi effettivamente correggere gli intervalli dell'asse x nella figura stessa. Dovrai farlo attraverso la tua rappresentazione dell'origine dati.

I dettagli:

Quindi a volte non avrò punti dati in una categoria, ma questo non mi importa.

Forse no, ma sarà importante per plotly.express. In particolare, se per "non hai dati" intendi che non hai record per tutte le categorie nel tuo set di dati per tutte le date. Vedi, plotly sembra impostare i valori dell'asse x sulle categorie che trova nei primi valori univoci per i Date = Xquali è A, B ,C. Ma non preoccuparti, ci occuperemo anche di questo. Usiamo una versione leggermente modificata dello screenshot dei tuoi dati (la prossima volta, fallo). Ho aggiunto le date effettive anziché X, Ye ridotto un po 'l'intervallo dei numeri poiché i tuoi dati particolari rovinano un po' l'animazione.

Se usiamo un approccio di animazione come questo:

fig = px.scatter(df1, x="Category", y="Price", animation_frame="Date",
                  color="Category", range_y=[0,20])

... otterrai due fotogrammi di animazione:

Grafico 1, fotogramma 1

Grafico 1, fotogramma 2

Ora, utilizziamo un approccio per assicurarci che tutte le categorie siano rappresentate per tutte le date come puoi trovare nel post Pandas: come includere tutte le colonne per tutte le righe anche se il valore manca in un dataframe con un formato lungo?

Ora otterrai:

Grafico 2, fotogramma 1

Grafico 2, fotogramma 2

Spero che questo sia quello che stavi cercando. Non esitate a farmi sapere se no! Otterrai un risultato leggermente diverso se lasci cadere la df1.fillna(0)parte. Ma lascio a te il compito di scherzare con tutte le opzioni disponibili nel file

Codice completo:

import pandas as pd
import plotly.express as px

df = pd.DataFrame({'Date': {0: '24.08.2020',
                              1: '24.08.2020',
                              2: '24.08.2020',
                              3: '25.08.2020',
                              4: '25.08.2020',
                              5: '25.08.2020'},
                             'Category': {0: 'A', 1: 'B', 2: 'C', 3: 'C', 4: 'E', 5: 'F'},
                             'Price': {0: 1, 1: 2, 2: 3, 3: 3, 4: 10, 5: 13}})

# make sure that all category variables are represented for
# all dates even though not all variables have values.
df['key']=df.groupby(['Date','Category']).cumcount()
df1 = pd.pivot_table(df,index='Date',columns=['key','Category'],values='Price')
df1 = df1.stack(level=[0,1],dropna=False).to_frame('Price').reset_index()
df1 = df1[df1.key.eq(0) | df1['Price'].notna()]
df1=df1.fillna(0)

# ploty express animation
fig = px.scatter(df1, x="Category", y="Price", animation_frame="Date",
                  color="Category", range_y=[0,20])

# some extra settings.
fig.update_layout(transition = {'duration': 20000})


fig.show()