Last active
October 6, 2023 23:12
-
-
Save banditkings/a6519260f1fc8c49c94153ff2f3a6db5 to your computer and use it in GitHub Desktop.
Random Walk animation in Plotly
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import numpy as np | |
import plotly.graph_objects as go | |
# A Random Walk animation in Plotly using a line and a marker for the current position | |
n = 200 | |
# Random Walk with n points | |
x = np.arange(n) | |
i = 0 | |
state = 0 # initial state | |
y = [state] | |
while i <= n: | |
state += np.random.normal(0, 0.001) | |
y.append(state) | |
i+=1 | |
# Specify the animation args here for the duration, etc | |
animation_args = [None, | |
{'frame': {'duration': 50, 'redraw': False}, | |
'fromcurrent': True, | |
'transition': {'duration': 10, | |
'easing': 'quadratic-in-out'} | |
}] | |
# Marker Styling | |
marker_args = {'size':20, 'color':'red', 'line':{'width':2}} | |
def make_frames(x, y): | |
"""Make a list of go.Frame() objects with the specified data""" | |
result = [] | |
n = len(x) | |
for i in np.arange(n): | |
data = [go.Scatter(x=x[:i+1], y=y[:i+1], mode='lines'), | |
go.Scatter(x=[x[i]], y=[y[i]], mode='markers+text', | |
opacity=0.5, marker=marker_args, | |
text=['Current Position'], | |
textposition='top right'), | |
] | |
result.append(go.Frame(data=data)) | |
return result | |
# Now, make the go.Figure() object with the `frames` parameter | |
fig = go.Figure( | |
data=[go.Scatter(x=[0], y=[0], mode='lines', name='line'), | |
go.Scatter(x=[0], y=[0], mode='markers+text', opacity=0.5, | |
marker=marker_args, | |
text=['Current Position'], | |
textposition='top right', | |
name='current_position')], | |
layout=go.Layout( | |
xaxis=dict(range=[0, n], autorange=False), | |
yaxis=dict(range=[np.min(y) * 1.5, np.max(y) * 1.5], autorange=False), | |
title="Random Walk Animation", | |
updatemenus=[dict( | |
type="buttons", | |
buttons=[dict(label="Play", | |
method="animate", | |
args=animation_args)])] | |
), | |
frames=make_frames(x, y) | |
) | |
fig.update_layout(template='seaborn') | |
fig.show() |
We can't add annotations because they're not a graph object, so I guess you could instead add a go.Scatter
with a text label if you wanted another moving annotation
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Weirdness here is that we control the speed of the animation in the button arguments. I guess the idea here is that we can make multiple buttons that have different animation properties on playback (i.e. make a 'full speed' button or a 'half speed' button, etc).
Otherwise the animation logic is all in the
frames
parameter in thego.Figure()
object, in which we use a list ofgo.Frame(data)
objects for each frame. Simple!