selectData from callback

Is there a way to set selectData of a figure so that it appear selected on the graph?
I know that it theoretically works (withput the display), if one figures out to retrieve {"points": [...]} to have it sent to selectData but the selection is then not shown on the graph, meaning all other points are not blurred etc.

As far as I understand, one could take the figure as State and set a selection via fig.add_selection(...). This however only addresses ranges or shapes but not single points right?

Hi @luggie ,

If I understand what you are looking for, I think you can try to jump into this example below :

When you want to Selection Data as an area of figure you can use Box Select or Lasso Select and other unselected area will be blurred. But, if you want to select a single point just used Click Data.

I think I didn’t make it clear enough what I meant. What I’m trying to do is:

@callback(
    Output('some_figure', 'selectedData'),
    Input('some_buttom', 'n_clicks'),
)
def programatically_select_data(n_clicks):
    return {'points': [{'curveNumber': 0, 'pointNumber': 0, ...}]}

This works. But it only selects the points but does not interact with the graph, meaning that it does not blur all not selected points

Hi @luggie ,

Have you try using selections attribute in update_layout method to get interaction when a point or some points are selected ?
You can set both box select or single point select using this attribute.

Here is an example:

from dash import Dash, dcc, html, Input, Output, callback

import plotly.express as px

import json
import pandas as pd

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']

app = Dash(__name__, external_stylesheets=external_stylesheets)

styles = {
    'pre': {
        'border': 'thin lightgrey solid',
        'overflowX': 'scroll'
    }
}


df = px.data.stocks()
fig = px.scatter(df, x='date', y="GOOG")

fig.update_traces(marker_size=12)
fig.update_layout(clickmode='event+select')
app.layout = html.Div([
    
    dcc.Graph(
        id='basic-plot',
        figure=fig
    ),
    html.Button("Click To Box Select",id='click-button1'),
    html.Button("Click Single Point",id='click-button2'),
    html.Div(className='row', children=[

        html.Div([
            dcc.Markdown("""
                **Selection Data**
            """),
            html.Pre(id='selected-data', style=styles['pre']),
        ], className='three columns'),

    ])
])



@callback(
    Output('basic-plot', 'figure',allow_duplicate=True),
    Input('click-button1', 'n_clicks'),prevent_initial_call='initial_duplicate'
)
def programatically_select_data(n_clicks=0):
    if n_clicks:
        fig.update_layout(selections = [
            dict(
                x0 = "2018-07-24 10:51:24.0417",
                x1 = "2018-09-20 00:42:21.74",
                y0 = 1.01237753083344,
                y1= 1.1746352235176878,
            )])
    return fig


@callback(
    Output('basic-plot', 'figure',allow_duplicate=True),
    Input('click-button2', 'n_clicks'),prevent_initial_call='initial_duplicate'
)
def programatically_click_data(n_clicks=0):
    if n_clicks:
        fig.update_layout(selections = [
            dict(
                x0 = "2018-03-05",
                x1 = "2018-03-05",
                y0 = 1.0524482730908842,
                y1= 1.0524482730908842,
            )])
    return fig

@callback(
    Output('selected-data', 'children',allow_duplicate=True),
    Input('basic-plot', 'selectedData'),prevent_initial_call='initial_duplicate')
def display_selected_data(selectedData):
    return json.dumps(selectedData, indent=2)

@callback(
    Output('selected-data', 'children',allow_duplicate=True),
    Input('basic-plot', 'clickData'),prevent_initial_call='initial_duplicate')
def display_clicked_data(selectedData):
    return json.dumps(selectedData, indent=2)

if __name__ == '__main__':
    app.run(debug=True)
2 Likes

Your minimal example works!
However, in my rather complex application it does not. Can you think of any setting that may stop this from working?

Hi @luggie ,

I think there are possibilities that cause code not run well, but from my point of view, the runnable code must be available so issues can be reproduced. :slightly_smiling_face:

yeah well sometimes one wishes that someone else solves one’s problems … :smiley:
In my case I had to deconstruct all my code just to understand that my seemingly float x/y axis values were actually strings …

1 Like