1

I built a simple web-app in dash where I have a scatterplot which the user can select points from. All the points that the user selects are shown in a text box output for visibility. All of this works fine, but the problem arises when I want to create a method that will pick points automatically and mark them on the plot. I want this to simulate the user's choices so the user may continue to interact with the plot as if he/she has chosen these points.
I have prepared a minimal example here:

from dash import Dash, html, dcc, Input, Output, State
import plotly.express as px
import plotly.graph_objects as go
import random


external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = Dash(__name__, external_stylesheets=external_stylesheets)
styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll',
        'width': '80%'
    }
}


def get_figure():
    fig = px.scatter(x=[0, 1, 2, 3, 4], y=[0, 1, 4, 9, 16])
    fig.update_layout({'height': 500,
                       'clickmode': 'event+select'})
    return fig


app.layout = html.Div(children=[
    dcc.Graph(
        id='graph1',
        figure=get_figure()
    ),
    html.Button('Generate random point clicks', id='generate-random-points-button'),
    html.Pre(id='selected-data', style=styles['pre']),
])


@app.callback(
    Output('graph1', 'figure'),
    Input('generate-random-points-button', 'n_clicks'),
    State('graph1', 'figure')
)
def generate_random_point_clicks(n_clicks, fig):
    if n_clicks == 0:
        return fig
    fig = go.Figure(fig)
    fig.update_traces(selectedpoints=random.sample(list(range(5)), 3))
    return fig


@app.callback(
    Output('selected-data', 'children'),
    Input('graph1', 'selectedData'))
def display_selected_data(selectedData):
    res = []
    if selectedData is not None:
        for point in selectedData['points']:
            res.append(str(point))
        return '\n'.join(res)


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

When you run this app this is how it will look like:
enter image description here

The problem is that I am updating selectedpoints attribute of the graph and not the selectedData. The points appear on the graph as if they are chosen but when the user clicks on more points all the automatic selections disappear. Plus I want the automatic selections to show in the text box. I tried updating selectedData via the callback but it didn't work for me.
Any help will be appreciated!

erap129
  • 910
  • 1
  • 8
  • 17

0 Answers0