Hi all,
I have built a Plotly figure that animates frames with a play/pause button and a slider.
It works well for a small number of frames but doesn’t scale to my project target number of frames (10,000).
Each frame is made up of 32 go.Mesh3d() objects, each representing a face of the soccer ball, and each having its own color based on a value I fetch in a Pandas dataframe.
I need to greatly improve the run time as currently it takes 5 to 10 minutes to load the 10,000 frames and then isn’t very responsive.
I have tried many things and extensively searched SO and Google already, resulting in a minor perf improvement with steps like:
- Using orjson instead of json for faster serializing.
- caching the soccer ball creation (as it is the same across all frames)
- Because these are Mesh3d objects, It seems there is no equivalent to ScatterGL for scatter charts.
For example that’s how I create the ball structure:
from const import ico_vertices, ico_faces, correction_dict
def get_icosahedron_structure():
data = []
for face in ico_faces:
face_dict = {
"type": "mesh3d",
"x": [ico_vertices[j][0] for j in face],
"y": [ico_vertices[j][1] for j in face],
"z": [ico_vertices[j][2] for j in face],
}
if (ind := ico_faces.index(face)) in correction_dict:
face_dict["i"] = correction_dict[ind].get("i", [])
face_dict["j"] = correction_dict[ind].get("j", [])
face_dict["k"] = correction_dict[ind].get("k", [])
data.append(face_dict)
return data
And this is what my figure looks like:
fig1 = go.Figure(
data=make_ico(df, opacity=opacity, colormap=colormap),
layout=go.Layout(
autosize=False,
width=900,
height=900,
margin=dict(l=40, r=40, b=40, t=40),
updatemenus=[
dict(
type="buttons",
direction="right",
buttons=[
dict(
label="▶",
method="animate",
args=[
None,
{
"frame": {"duration": duration, "redraw": True},
"fromcurrent": True,
"transition": {"duration": 0, "easing": "quadratic-in-out"},
},
],
),
dict(
label="◼",
method="animate",
args=[
[None],
{
"frame": {"duration": 0, "redraw": False},
"mode": "immediate",
"transition": {"duration": 0},
},
],
),
],
)
],
),
frames=[
go.Frame(
data=make_ico(
df, time=i, opacity=opacity, colormap=colormap
),
layout=go.Layout(
title_text=(timestamp := str(df.iloc[i, 0]))
),
name=timestamp,
)
for i in range(len(df))
],
)
The slow part in the snippet above is the list of frames.
I’m using Python 3.10 and Plotly 5.7.0
Let me know if you need a full minimal reproducible example.
So my question is: do you have any suggestions as to how to speed up the figure creation and/or its rendering?
Thanks vm!
Clem