Scattergl and updating go.Figure.frames --> r[v] undefined

Context

I have a scattergl with many datapoints. Therefore, created an animation using shapes. It works wonderful until I update the frames for the second time in the callback. I check that all data still exists, and it does, so it should be drawn. But checking the dev console in the brower it says:

Uncaught TypeError: r[v] is undefined

Code is functional if I use go.Scatter instead of go.Scattergl. I traced the error back to the source code:

    // form batch arrays, and check for selected points
    var dragmode = fullLayout.dragmode;
    var isSelectMode = selectMode(dragmode);
    var clickSelectEnabled = fullLayout.clickmode.indexOf('select') > -1;

    for(i = 0; i < count; i++) {
        var cd0 = cdata[i][0];  //This is what causes "r[v] is undefined" in the plotly.min.js
        var trace = cd0.trace;
        var stash = cd0.t;
        ...

Link:

So in plotly.min.js, r[v][0] refers to cdata[i][0]

This is as far as I’ve gotten. I’m unable to figure it out and could really use some help.

My code

Figure setup:

  fig = go.Figure(
      layout=go.Layout(
          updatemenus=[dict(
              type="buttons",
              buttons=[dict(label="Play",
                            method="animate",
                            args=[None, dict(frame=dict(duration=60//1000, redraw=False))])])]
      )
  )

  for cluster in range(cluster_ids):
      msk = cluster_labels == cluster
      x, y = embedding[msk].T
      fig.add_trace(
          go.Scattergl(
              x=x,
              y=y,
              name=f'Cluster {cluster}',
              mode='markers',
              marker=dict(color=CLUSTER_COLORS[cluster], size=MARKER_SIZE),
              hoverinfo='skip'
          )
      )

#update layout...

Code for creating frames

        frames=[]
        for H, T in zip(head, tail):
            head_circle = get_svg_circular_path(H[0], H[1], r)  # calculates circle as svg to prevent resizing
            tail_circle = get_svg_circular_path(T[0], T[1], r)  # calculates circle as svg to prevent resizing
            frame = go.Frame(
                layout=dict(
                    shapes=[
                        dict(type="line", x0=T[0], y0=T[1], x1=H[0], y1=H[1], fillcolor='#636EFA'),
                        dict(type='path', path=head_circle, **path_kwargs),
                        dict(type='path', path=tail_circle, **path_kwargs),
                    ],
                ),
            )

            frames.append(frame)

Callback

    @callback(
        Output('graph-id', 'figure'),
        [
            Input('calculate-button', 'n_clicks'),
            State({'type': 'value-sliders', 'index': ALL}, 'value'),
            # State('graph-id', 'figure') <-- using the fig's data object has same effect
        ]
    )
    def calculate_new_fig(n_clicks, values):
        # removed some code for readability
        # but the essence is that I use to the values to update the animation location
        fig = get_initial_map()  # this get the figure earlier code snippet
        if n_clicks:
            frames = get_frames() 
            fig.update(frames=frames)
            return fig
        return fig

What I’ve tried

I’ve tried re-creating the figure, using the dcc.Graph figure atribute, extending the list with frames instead of overriding, reduce scattergl size (as in number of datapoints), adding data dict to go.Frame, and redraw True.

Notable observations

Code 100% works if I replace the go.Scattergl with go.Scatter.

First time the frame are added the animation plays perfectly smooth. When I then update the frames with a new animation, the animation is shown, but the points in the Scattergl dissappear. So animation - yes, data - no.

Additionally, when printing the fig.data[0] datastructure, everything is EXACTLY the same each iteration. So, first, second, third, nth animation frames. It just DOES NOT get drawn and I see and Uncaught TypeError: r[v] is undefined in the console. Note that app doesn’t crash.

Help! :slight_smile:

I found a workaround, see go.Scattergl disappears but go.Scatter does not (Animation using Shapes) - #2 by daeverb