ScatterGL bug in Dash

The new ScatterGL is great - but there might be a bug. I can’t provide a video/screen but hopefully someone can help reproduce it as follows. Dependencies:

plotly (2.3.0)
dash (0.20.0)
dash-core-components (0.18.1)
dash-html-components (0.8.0)
dash-renderer (0.11.2)
  1. Include a dropdown callback with multi=True
  2. Use Scattergl instead of Scatter. Include text= in your options for the scatter and mode=markers
  3. Have an initial selection from the dropdown so data loads automatically
  4. After loading (scatter points all load fine), add a second choice from the dropdown. Data and scatter points are shown for both selections
  5. Remove the first (default) choice from the dropdown. The scatter points for the second dropdown choice should be shown, but instead it’s blank. Curiously, if you hover over the chart, the text for each point displays but the points themselves are blank.

Ideas welcome. @chriddyp , I can send videos etc privately if needed.

Will

1 Like

Thanks for reporting @will! Most likely a bug. I’ll work on a small reproducable example and update this thread with more info.

@will - Are there any other options set in dcc.Graph? For example, is animate=True?

@will - So far, I’m unable to reproduce the issue. I’ve tried to create a reproducable example as below. Is there anything that I’m missing?

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd

app = dash.Dash()

df = pd.DataFrame({
    'x': [1, 2, 3, 1, 2, 3],
    'y': [3, 1, 2, 4, 2, 3],
    'text': ['a', 'b', 'c', 'd' ,'e', 'f'],
    'filter': ['a', 'a', 'a', 'b', 'b', 'b']
})

app.layout = html.Div([
    dcc.Dropdown(
        multi=True,
        id='dropdown',
        options=[{'label': i, 'value': i} for i in ['a', 'b']],
        value=['a']
    ),
    dcc.Graph(
        id='graph'
    )
])

@app.callback(Output('graph', 'figure'), [Input('dropdown', 'value')])
def update_graph(value):
    dff = df[df['filter'].str.contains('|'.join(value))]
    return {
        'data': [{
            'x': dff['x'],
            'y': dff['y'],
            'text': dff['text'],
            'mode': 'markers',
            'type': 'scattergl'
        }]
    }

if __name__ == '__main__':
    app.run_server(debug=True)

Ah, good spot Chris - it does have animate. Try it with this:

        id='graph',animate=True)

Seems broken

OK, got it. I’d try removing animate=True for now - it currently doesn’t work for graphs that are adding or removing traces. Also, animations are only supported for the SVG-style charts (as they use CSS animations) and not for the WebGL style charts.

What does animate=True do here exactly? Simply call Plotly.animate instead of Plotly.newPlot or something more convoluted?

This. Reference code: https://github.com/plotly/dash-core-components/blob/92ca076ec5235704b9d4ed2fbb4ca907995ffbfa/src/components/Graph.react.js#L76-L82

1 Like

This should be fixed in the next plotly.js release 1.34.0

1 Like

@chriddyp I’m encountering a similar bug. I have a function to generate a ScatterGL graph, from which I’m generating a list of html.Div with differing scatters. As long as I have 8 or less rendered, they display fine. Any more, and the older ones have the same problem @will described. Minimal example, my scatter function is called: get_scatter.

def get_scatter_divs():
    scatters = []

    for param in range(12):
        scatter = html.Div([get_scatter(param)])
        scatters.append(scatter)


    # scatters = scatters[:9]
    return scatters

get_scatter_divs is called in the layout within a div. As is, then 4 of the scatter plots are missing the markers even though the hover data is still viewable. If I uncomment the line, then they all work. I’ve made sure that the figure IDs are all unique, and that I don’t have animate=True. I’m not really sure how to fix this, as I was hoping to scale up to more plots and creating them all dynamically would be ideal. Any help would be appreciated.

Here’s a gif. When you get the markers the display on one, it removes them from another plot.