Get 'selected data' in a parallel coordinates chart to update table - Resolved

Hello,

I want to update a table based on the constraint range filter in a parallel coordinates chart. There are two questions pertaining for this use case.

  1. How to obtain the selected data?
  2. How to fire a callback when constraint range is changed to update the table?
1 Like

I found about restyleData for the parallel coordinate chart and I am able to obtain the constraint range for the last changed constraint.

Hi, will you be able to share how to generate the callbacks between parallel coordinates and table ? I want to do the same and struggle a little bit. Thanks, Matthieu

Sure. Here is what I’m doing.

I use restyleData as input to the callback function. Something like this

@app.callback(Output('parallel-coord-graph', 'figure'),
              [Input('par-coord-dropdown', 'value'),
               Input('parallel-coord-graph', 'restyleData')],
              [State('parallel-coord-graph', 'figure'),
               State('metric-range', 'children')])
def update_par_coord_graph(dropdown_input, restyledata, par_coord_data,
                           metric_info):

    par_coord_data = par_coord_data['data'][0]
    curr_dims = par_coord_data.get('dimensions', None)

# Relevant restyleData Code

        # Update the constraint ranges for the new restyled dimension
        # Format of resytledata: [{'dimension[0].constraintrange': [0,1]}]
        if restyledata:
            for key, val in restyledata[0].items():
                dim = int(re.split(r'\[|\]', key)[1])
                updated_constraints[dropdown_input[dim]] = val[0]

Note the format of restyledata which is a dict.

To update the table, I use figure attribute to extract the state of the parallel coordinate chart. Something like this -

@app.callback(Output('table', 'children'),
              [Input('parallel-coord-graph', 'figure')])
def test_me(par_coord_data):

    par_coord_data = par_coord_data['data'][0]
    curr_dims = par_coord_data.get('dimensions', None)

Hope this helps!
Lakshay

3 Likes

Hi, I tried but unfortunately by selecting on a parcoord axis, the callback is not activated. Is there a way for you to share with me an example ? Regards, Matthieu

2 Likes

Is it possible to use restyleData when we unselect the filter from parcoords axis?
I’ve tried any graph properties including restyleData, but it doesn’t trigger new output. The output still showing the last {dimension,constraintrange} we selected.

selected axis in parallel coordinates to update bubble chart.
welcome to check out my explaination in medium :

@app.callback(
    [Output('scatter-plot', 'figure'),
     Output('parallel-coordinates-plot', 'figure'),
     Output('selected-countries', 'data')],
    [Input('x-axis-dropdown', 'value'),
     Input('country-dropdown', 'value'),
     Input('scatter-plot', 'clickData'),
     Input('parallel-coordinates-plot', 'restyleData'),
     Input('clear-selection-button', 'n_clicks')],
    [State('selected-countries', 'data')]
)
# Handle parallel coordinates constraintrange (restyleData)
    elif triggered_id == 'parallel-coordinates-plot' and parallel_restyle_data:
        constrained_df = df.copy()  # Start with the full dataframe

        # Track selections progressively by applying constraints from parallel coordinates plot
        if parallel_restyle_data:
            for item in parallel_restyle_data:
                if isinstance(item, dict):  # Ensure item is a dictionary
                    for key, value in item.items():
                        if 'constraintrange' in key:
                            # Extract dimension index and label
                            dimension_index = int(key.split('[')[1].split(']')[0])
                            dimension_label = explained_columns[dimension_index]

                            # Apply constraints
                            constrain_range = value
                            if isinstance(constrain_range[0], list):
                                mask = np.logical_or.reduce([constrained_df[dimension_label].between(r[0], r[1]) for r in constrain_range])
                            else:
                                mask = constrained_df[dimension_label].between(constrain_range[0], constrain_range[1])

                            constrained_df = constrained_df[mask]

            # Get the unique countries that meet the new axis constraints
            selected_countries_from_parallel = constrained_df['Country name'].unique().tolist()

            # Intersect the newly selected countries with the previously selected countries
            if selected_countries:
                selected_countries = list(set(selected_countries).intersection(set(selected_countries_from_parallel)))
            else:
                selected_countries = selected_countries_from_parallel

            # Print the selected countries for debugging
            print(f"Selected countries from parallel coordinates plot: {selected_countries}")

            # Filter based on updated selected countries
            filtered_df = df[df['Country name'].isin(selected_countries)]
        else:
            filtered_df = df