Plotly-Python Mesh3d animation performance issue

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.

dXQum

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