Plotly: Como especificar elementos categóricos do eixo x em uma animação expressa em plotagem?

Aug 22 2020

Eu tenho os seguintes dados.

Estou usando um controle deslizante, para que possa deslizar pelas diferentes datas (por favor, veja a imagem abaixo para ver o que é um controle deslizante no caso).

Agora, como minha categoria pode mudar entre as datas, quero inicializar meu intervalo do eixo x com A, B, C, E, F, não importa qual seja a minha data. Às vezes, não terei pontos de dados em uma categoria, mas isso não importa para mim.

Então, como posso inicializar meu intervalo do eixo x e fazer meus pontos de dados se adaptarem ao eixo x inicializado?

Estou usando o python3 e o plotly express.

Este é o meu código por enquanto:

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)

Espero ter sido claro o suficiente. Por favor, deixe-me saber se você precisar de alguma informação extra. Quaisquer ideias ou dicas são bem-vindas :)

Respostas

vestland Aug 23 2020 at 22:56

A resposta:

A única maneira de garantir que todas as categorias sejam representadas no eixo x para todos os quadros de animação é certificando-se de que apareçam no primeiro Date = X. Portanto, você não pode realmente corrigir os intervalos do eixo x na própria figura. Você terá que fazer isso por meio de sua representação da fonte de dados.

Os detalhes:

Às vezes, não terei pontos de dados em uma categoria, mas isso não importa para mim.

Talvez não, mas vai importa para plotly.express. Particularmente se você por "não tiver dados" significa que você não tem registros para todas as categorias em seu conjunto de dados para todas as datas. Veja, plotly parece definir os valores do eixo x para as categorias que encontra nos primeiros valores únicos para os Date = Xquais é A, B ,C. Mas não se preocupe, nós cuidaremos disso também. Vamos usar uma versão ligeiramente alterada de sua captura de tela de dados (da próxima vez, faça isso). Eu adicionei datas reais em vez de X, Ye reduzi um pouco o intervalo dos números, já que seus dados específicos bagunçam um pouco a animação.

Se usarmos uma abordagem de animação como esta:

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

... você obterá dois quadros de animação:

Plot 1, frame 1

Plot 1, frame 2

Agora, vamos usar uma abordagem para garantir que todas as categorias sejam representadas para todas as datas, como você pode encontrar na postagem Pandas: Como incluir todas as colunas para todas as linhas, embora o valor esteja faltando em um dataframe com um formato longo?

Agora você obterá:

Plot 2, frame 1

Plot 2, frame 2

Espero que seja isso que você estava procurando. Não hesite em me dizer se não! Você obterá um resultado ligeiramente diferente se descartar a df1.fillna(0)peça. Mas vou deixar para você mexer em todas as opções disponíveis no

Código 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()