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:
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!