Dash plotly line chart animation does not work with line in year-to-year direction

Question:

I have a dataframe like this:

enter image description here

The code like this:

bolas = df3_virada.iloc[:,1:8]

b1 = list(bolas.b1)
b2 = list(bolas.b2)
b3 = list(bolas.b3)
b4 = list(bolas.b4)
b5 = list(bolas.b5)
b6 = list(bolas.b6)

fig = px.line(bolas, x='data', y=[b1,b2,b3,b4,b5,b6], markers=True, template='seaborn', 
            text='value', height=600, animation_frame=ano)

fig.update_traces(textposition='top center')

However, the graph looks like this. Only the numbers change fixed in the same place.

enter image description here

I want the lines to form year by year in the animation as shown in this image:

enter image description here

I’ve tried everything but I couldn’t make this animation, if anyone can help me, I appreciate it.

Asked By: MJAGO

||

Answers:

The animation structure requires data, animation frame, and layout, so in the case of a line chart, create the initial data up to the starting year or the following year. Next, add frames as animation frames, also in line mode for scatter plots, with increasing end years. From the sample data presented, the graph is created with an aggregated data frame of the required columns. express will not animate the data, so it is created with a graph object. Please refer to the reference for an example with a graph object.

df['data'] = pd.to_datetime(df['data'])
df['year'] = df['data'].dt.year
df = df[['year','b1','b2','b3','b4','b5','b6']]
df.head()
    year    b1  b2  b3  b4  b5  b6
0   2009    10  27  40  46  49  58
1   2010    2   10  34  37  43  50
2   2011    3   4   29  36  45  55
3   2012    14  32  33  36  41  52
4   2013    20  30  36  38  47  53

import plotly.graph_objects as go
import numpy as np

sliders = [dict(steps = [dict(method= 'animate',
                              args= [[f'{k}'],                           
                              dict(mode= 'immediate',
                                   frame= dict(duration=500, redraw=False),
                                   transition=dict(duration= 0))
                                 ],
                              label=f'{k}'
                             ) for k in df.year.unique()], 
                active=0,
                transition=dict(duration=0),
                x=0.1, # slider display start position  
                y=0, 
                currentvalue=dict(font=dict(size=12), 
                                  prefix='frame: ', 
                                  visible=True, 
                                  xanchor= 'center'
                                 ),  
                len=0.9) #slider length
           ]


layout = go.Layout(autosize=False,
                   height=600,
                   width=1000,
                   template='seaborn',
                   xaxis=dict(tickvals=np.arange(2008,2022,1)),
                   updatemenus=[dict(type='buttons',showactive=False,
                                     x=0.1, y=0,
                                     xanchor='right',
                                     yanchor='top',
                                     pad=dict(r=10,t=40),
                                     direction='left',
                                     buttons=[dict(label='Play',
                                                   method='animate',
                                                   args=[None,
                                                         dict(frame=dict(duration=500,
                                                                         redraw=False),
                                                    trasition=dict(duration=300),
                                                    fromcurrent=True,
                                                    mode='immediate')]),
                                             dict(label='Pause',
                                                  method='animate',
                                                  args=[None, 
                                                        dict(frame=dict(duration=0,
                                                                         redraw=False),
                                                    trasition=dict(duration=0),
                                                    mode='immediate')])
                                             ])])                      
                                              


layout.update(xaxis=dict(range=[2008.5, 2021.5], autorange=False))
layout.update(sliders=sliders)

trace1 = go.Scatter(x=[2009,2010], y=df['b1'][0:2], mode='lines+text', text=df['b1'][0:2], textposition='top center', line=dict(width=1.5), name='b1')
trace2 = go.Scatter(x=[2009,2010], y=df['b2'][0:2], mode='lines+text', text=df['b2'][0:2], textposition='top center', line=dict(width=1.5), name='b2')
trace3 = go.Scatter(x=[2009,2010], y=df['b3'][0:2], mode='lines+text', text=df['b3'][0:2], textposition='top center', line=dict(width=1.5), name='b3')
trace4 = go.Scatter(x=[2009,2010], y=df['b4'][0:2], mode='lines+text', text=df['b4'][0:2], textposition='top center', line=dict(width=1.5), name='b4')
trace5 = go.Scatter(x=[2009,2010], y=df['b5'][0:2], mode='lines+text', text=df['b5'][0:2], textposition='top center', line=dict(width=1.5), name='b5')
trace6 = go.Scatter(x=[2009,2010], y=df['b6'][0:2], mode='lines+text', text=df['b6'][0:2], textposition='top center', line=dict(width=1.5), name='b6')

 frames = [dict(data=[go.Scatter(x=df.year[:k+1], y=df.b1[:k+1], text=df.b1[:k+1], textposition='top center', name='b1'),
                     go.Scatter(x=df.year[:k+1], y=df.b2[:k+1], text=df.b2[:k+1], textposition='top center', name='b2'),
                     go.Scatter(x=df.year[:k+1], y=df.b3[:k+1], text=df.b3[:k+1], textposition='top center', name='b3'),
                     go.Scatter(x=df.year[:k+1], y=df.b4[:k+1], text=df.b4[:k+1], textposition='top center', name='b4'),
                     go.Scatter(x=df.year[:k+1], y=df.b5[:k+1], text=df.b5[:k+1], textposition='top center', name='b5'),
                     go.Scatter(x=df.year[:k+1], y=df.b6[:k+1], text=df.b6[:k+1], textposition='top center', name='b6')
                     ],
               name=f'{y}',
               traces= [0, 1, 2, 3, 4, 5, 6],  
              )for y,k  in  zip(df.year.unique()[1:], range(1, len(df)+1))]


fig = go.Figure(data=[trace1, trace2, trace3, trace4, trace5, trace6], layout=layout, frames=frames)

fig.show()

enter image description here

Answered By: r-beginners