Remove selection from subplot without triggering selectedData callback

Hi,
I created a figure with multiple subplots that show line plots. When the user makes a (box) selection in one of them, I want to remove the selection from the other plot that has a selection. I planned to just update the selections in the layout:

figure["layout"]["selections"] = list(filter(lambda s: s["xref"] == x_ref, selections))

This works but triggers the callback again because I updated the selections. The newly triggered selection does not contain any relevant data, by the way, which makes this behavior completely useless… So I guess this is both a question and a bug report :sweat_smile:

Is there a way to remove a selection from a subplot without triggering any selectedData callback?

Thanks!

1 Like

Hi @meffadd, it sounds like you had circular dependencies in your callbacks? Are your callbacks taking selectedData as both Input and Output?

I had a similar question and your code inspired me. I had four subplots in my figure. By default, the user could draw at most one box in each subplot. So, there can be at most four boxes present in the figure at a time. But I wanted to limit it to one, so that if the user has drawn a box in any subplot and wants to draw a second one in a different subplot, the first one would disappear soon after the second one is drawn. What worked for me was something like the following

@app.callback(
    Output("graph", "figure", allow_duplicate=True),
    Input("graph", "selectedData"),
    State("graph", "figure"),
    prevent_initial_call=True,
)
def read_box_select(box_select, figure):
    selections = figure["layout"].get("selections")
    if not selections:
        return dash.no_update
    if len(selections) > 1:
        selections.pop(0)
    return figure

Where “graph” is the id of the dcc.Graph component that contains the figure. figure[“layout”][“selections”] appends the box in the order in which the user draws them. So doing pop(0) removes the previously drawn box, and achieves what I wanted.