1

for a project for a hospital, I've been trying to create a dashboard so I can display my data to healthcare professionals in a way they can understand. I'm completely new to Dash and plotly, I've always used matplotlib for my visualisation needs, and I'm really struggling to handle clickevents, especially since all online resources seem to assume you're working with a predefined plot, whereas I'm accessing a bigger dataset and only plotting the relevant plots on demand.

I'm especially struggling since my main callback function handles the div and children, and I'm seemingly not able to save the ID of the graph that is being clicked. I need to handle the clicks specifically for the graph that's being clicked. I'll share a few code snippets that would hopefully give you an idea of what I'm trying to achieve.

app = dash.Dash(__name__) # App layout app.layout = html.Div([ dcc.Dropdown( id='patient-dropdown', options=[{'label': patient_id, 'value': patient_id} for patient_id in sorted_patient_ids], value=[sorted_patient_ids[0]], # Default value multi=True # Allows selecting multiple options ), dcc.Checklist( id='six-weeks-line-toggle', options=[{'label': '6-week line', 'value': 'SWL'}], value=[] ), dcc.Checklist( id='t-dates-toggle', options=[{'label': 'Show t0 to t4 dates', 'value': 'SHOW_T_DATES'}], value=[] ), dcc.Dropdown( id='question-dropdown', options=[{'label': question, 'value': question} for question in questions], # multi=True # Allows selecting multiple options ), dcc.Checklist( id='volume-of-notes-toggle', options=[{'label': 'Show volume of notes', 'value': 'SHOW_VOLUME_OF_NOTES'}], value=[] ), html.Div(id='graphs-container'), html.Div(id='notes-display', style={'white-space': 'pre-line'}), dcc.Graph(id='patient-plot') ]) @app.callback( Output('graphs-container', 'children'), [Input('patient-dropdown', 'value'), Input('six-weeks-line-toggle', 'value'), Input('t-dates-toggle', 'value'),Input('question-dropdown', 'value'), Input('volume-of-notes-toggle', 'value')] ) def update_graphs_container(selected_patient_ids, toggle_values, t_dates_toggle, selected_questions, volume_of_notes_toggle): graphs = [] for selected_patient_id in selected_patient_ids: fig = update_figure(selected_patient_id, toggle_values, t_dates_toggle, selected_questions, volume_of_notes_toggle) graphs.append(dcc.Graph(figure=fig)) return graphs 

The update_figure function handles all settings the user can use, like displaying additional useful indicators for when important events happened for the patient (i.e. admission and surgery dates). I believe I should add the clickEvent handler in this function, but I'm not sure how. For now, it'd be a huge help if you could help me implement a placeholder strategy, that basically returns the date (x-axis) of a datapoint when being clicked. I believe I should give the graphs unique IDs, but I'm really not certain.

If you need more snippets of my code, I'm happy to share, but I'll have to make some changes for privacy reasons.

Thanks in advance!

1 Answer 1

0

You need to set a composite id (ie. using a dictionary rather than a string) for each graph created so that you can leverage Dash pattern matching callback :

@app.callback( Output('graphs-container', 'children'), [Input('patient-dropdown', 'value'), Input('six-weeks-line-toggle', 'value'), Input('t-dates-toggle', 'value'),Input('question-dropdown', 'value'), Input('volume-of-notes-toggle', 'value')] ) def update_graphs_container(selected_patient_ids, toggle_values, t_dates_toggle, selected_questions, volume_of_notes_toggle): graphs = [] for selected_patient_id in selected_patient_ids: fig = update_figure(selected_patient_id, toggle_values, t_dates_toggle, selected_questions, volume_of_notes_toggle) graph_id = {'type': 'graph', 'patient_id': selected_patient_id} graphs.append(dcc.Graph(id=graph_id, figure=fig)) return graphs 

This allows to register and use only one generic callback to handle clickData inputs (or any other supported property) for any components of type 'graph' (using MATCH, ALL, or ALLSMALLER). Assuming you need to receive only the MATCHing graph's clickData (the graph on which user clicked), you can do something like this :

@callback( Output('<some_id>', '<some_property>'), Input({'type': 'graph', 'patient_id': MATCH}, 'clickData'), prevent_initial_call=True ) def handle_click(clickData): print(clickData) something = do_something(clickData) return something 

If for example you need to update the matching graph's figure in the callback, use the MATCH selector just as for the input, ie. Output({'type': 'graph', 'patient_id': MATCH}, 'figure').

Sign up to request clarification or add additional context in comments.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.