Reputation: 35
I have a dataframe like this:
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.
I want the lines to form year by year in the animation as shown in this image:
I've tried everything but I couldn't make this animation, if anyone can help me, I appreciate it.
Upvotes: 1
Views: 275
Reputation: 35155
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()
Upvotes: 1