Black Lives Matter. Please consider donating to Black Girls Code today.

Knowing what graph has been clicked

First of all, thank you for creating plotly and dash they are awesome tools for visualising data.

Back to my question:

  • I have the following code:
@app.callback(
    output=dash.dependencies.Output('display-images', 'figure'),
    inputs=[
        dash.dependencies.Input('graph-stats-metric', 'clickData'),
        dash.dependencies.Input('graph-metric-frames', 'clickData'),
    ],
    state=[
        dash.dependencies.State('table-summary', 'selected_row_indices'),
    ]
)
def update_images(click_stats, click_frames, indices):
    if click_stats is None:
        return update_images_from_frames(click_frames, indices)
    elif click_frames is None:
        return update_images_from_stats(click_stats, indices)

In it, I would like to update the figure in my display-images graph whenever the user clicks on 2 other graphs graph-stats-metric and graph-metric-frames. However I would like to update it in a slightly different way depending on which one of the 2 previous graphs is clicked. At the moment, the variables click_stats and click_frames are None at the beginning and they get set to the correct values once the user clicks on the graph-stats-metric and graph-metric-frames graphs. However, the values of this variables do not flush (they seem to remain set to the last point that was clicked) so if the user clicks on both graphs (first one and then the other) there is no way for me to know which one was clicked last, which is the one I would like to use to update the figure in the display-images graph. Is there a work around that will allow me to implement this behaviour?

Many thanks for your help.

AFAIK there is currently no good way to do this within the Dash design, see the discussion in dash/#59 and dash/#140 for a future solution.

However, I found the workaround suggested in this thread Sharing a dataframe between plots to be very effective. In your case, you would create a hidden Div for each click (one for graph-stats-metric and one for graph-metric-frames) that records the timestamp of the click. Then your display-images update callback would depend on these hidden Div children, which contain the timestamp, as well as optionally the state of the two graphs. The callback can then see which click was the latest.

This can be extended in some nice ways, for instance only updating the timestamp on certain conditions on the state of the object being clicked on (or other actions), so that you can basically record a specific type of interaction. You do have to be careful of the potential complications mentioned in that thread.

1 Like