Announcing Dash Bio 1.0.0 🎉 : a one-stop-shop for bioinformatics and drug development visualizations.

Multiple indexed inputs affecting a single output in a callback - possible?

I have a 3 x 3 grid of plots where the plots in each column are of a specific type: column 1 contains bar+line plots, column 2 has waterfall charts and column three is a scatter plot. By clicking on a data point of any plot in the first column, the corresponding chart in the second column is updated. For example, clicking chart 2 in column 1 filters chart 2 in column 2. The same is true when clicking on a data point in charts in column 2 - the corresponding plot in column 3 is updated. To achieve this I used 2 pattern-matching callbacks.

The plots in my columns (layout) have the following IDs

Column 1

id={'type': 'barline', 'index': 'a'}
id={'type': 'barline', 'index': 'b'}
id={'type': 'barline', 'index': 'c'}

Column 2

id={'type': 'waterfall', 'index': 'a'}
id={'type': 'waterfall', 'index': 'b'}
id={'type': 'waterfall', 'index': 'c'}

Column 3

id={'type': 'scatter', 'index': 'a'}
id={'type': 'scatter', 'index': 'b'}
id={'type': 'scatter', 'index': 'c'}

What I want to do next is have a click in the final column (on any chart) update just a single output. I tired the following callback but it won’t work:

@app.callback(
    Output('output-location', 'children'),
    Input({'type': 'scatter', 'index': MATCH}, 'clickData'),
    prevent_initial_call = True
)
def generate_insight(click):
    if click is None:
        raise PreventUpdate
    else:
        parameter_1 = click['points'][0]['x']
        parameter_2 = click['points'][0]['customdata'][0]
        parameter_3 = click['points'][0]['customdata'][1]
        return generate_output_function(parameter_1, parameter2, parameter3)

I have considered giving all my charts their own IDs, rather than indexing them and using pattern-matching callbacks, but the code becomes quite large.

Any help would be greatly appreciated!

Hi,

The MATCH pattern requires to have a “matched” id in the Output. In your case, the quickest alternative would be to replace the callback with an ALL index and handle the list of clickData in the callback body.

If you need to figure out which one of the index triggered the callback, you can use the callback context.

I believe you want to return a component with the data from the latest clicked graph, so the callback context will be important to select which element of the list will be used.

Thank you! I had to read up on callback_context and it was just what I needed. Working like a charm now!