Hi there,
Iβm willing to animate time evolving data, with possibly many frames (several thousands).
The data it self is not big (dozens of dots and lines), but the rendering is very slow.
I could downsample the data, but Iβm willing to do so as a last resort.
I am looking for possible optimization of the code below (as NB_FRAMES gets >200, it starts to slow down), or is this a limitation of plotly (or the browser ?),
Thanks.
import numpy as np
import plotly.graph_objects as go
def genx_data(k):
return np.cos(k)
def geny_data(k):
return np.sin(k)
def genz_data(k):
return k
NB_FRAMES = 200
# Create figure
fig = go.Figure(go.Scatter3d(x=[], y=[], z=[],
mode="markers",
marker=dict(color="red", size=10),
name= "Marker"
)
)
fig.add_scatter3d(name='Trace', mode="lines", line_width=2)
fig.add_scatter3d(x=[], y=[], z=[], mode="markers", marker=dict(color="blue", size=10), name="Marker")
fig.add_scatter3d(name='Trace', mode="lines", line_width=2)
fig.update_layout(scene=dict(xaxis=dict(range=[-10, 10]),
yaxis=dict(range=[-10, 10]),
zaxis=dict(range=[-10, 10]),
aspectmode="cube"
),
)
s = np.linspace(-10, 10, NB_FRAMES)
# Frames
frames = [go.Frame(data=[go.Scatter3d(x=[genx_data(s[k+1])],
y=[geny_data(s[k+1])],
z=[genz_data(s[k+1])],
),
go.Scatter3d(x=genx_data(np.linspace(s[max(0, k-25)], s[k + 1], 20)),
y=geny_data(np.linspace(s[max(0, k-25)], s[k + 1], 20)),
z=genz_data(np.linspace(s[max(0, k-25)], s[k + 1], 20)),
),
go.Scatter3d(x=[genz_data(s[k+1])],
y=[geny_data(s[k+1])],
z=[genx_data(s[k+1])],
),
go.Scatter3d(x=genz_data(np.linspace(s[max(0, k - 25)], s[k + 1], 20)),
y=geny_data(np.linspace(s[max(0, k - 25)], s[k + 1], 20)),
z=genx_data(np.linspace(s[max(0, k - 25)], s[k + 1], 20)),
),
],
traces=[0, 1, 2, 3],
name=f'frame{k}',
) for k in range(len(s)-1)
]
fig.update(frames=frames)
def frame_args(duration):
return {
"frame": {"duration": duration},
"mode": "immediate",
"fromcurrent": True,
"redraw": False,
}
sliders = [
{"pad": {"b": 10, "t": 60},
"len": 0.9,
"x": 0.1,
"y": 0,
"steps": [
{"args": [[f.name], frame_args(0)],
"label": str(k),
"method": "animate",
} for k, f in enumerate(fig.frames)
]
}
]
fig.update_layout(
updatemenus=[{"buttons": [
{
"args": [None, frame_args(0)],
"label": "Play",
"method": "animate",
},
{
"args": [[None], frame_args(0)],
"label": "Pause",
"method": "animate",
}],
"direction": "left",
"pad": {"r": 10, "t": 70},
"type": "buttons",
"x": 0.1,
"y": 0,
}
],
sliders=sliders
)
fig.update_geos(projection_type="equirectangular", visible=True, resolution=50)
fig.update_layout(sliders=sliders)
fig.show()