plotly / plotly/dash

Selected points returning after being cleared and shift+clicking as first click

Open
#1,572 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

bug P3
Dominant language
Python
Stars
24.4k
Forks
2.3k
Avg merge
2d 7h
Merged PRs (30d)
13

Description

Describe your context

dash                                  1.19.0
dash-core-components                  1.15.0
dash-html-components                  1.1.2
dash-renderer                         1.9.0
dash-table                            4.11.2

Describe the bug
So far I've been able to fix most of the issues, but one that has gotten me really stuck is dealing with the little 'x' in the dropdown. It correctly activates the callback that contains logic to restore the selectedpoints to the scatterplot. However after that is completed and the graph is restored if I shift + click a different square it returns me to my previous selection which shouldn't exist because I just replaced it. I checked the variables and the selectedpoints values and the dropdown values were all successfully changed.

No callbacks occur when I shift+click afterwards even though I have a callback.
Regular clicking is fine

I suppose this could be the intended behavior, but seems a little strange.

Expected behavior

I expected the shift+clicked marker to be the only selection.

Screenshots

plotly

Code

@app.callback(
    Output('station-dd', 'value'),
    [Input('all-graph', 'selectedData')],
    [State('station-dd', 'value')])
def add_to_dd(sel_from_graph, val_in_dd):
    if sel_from_graph is None:
        return None
    else:
        selected_list = []
        for x in sel_from_graph['points']:
            idx = x['customdata'][6]
            selected_list.append(idx)
        if val_in_dd:
            if len(selected_list) == 1:
                result_list = selected_list
            else:
                result_list = list(set(selected_list) | set(val_in_dd))
                result_list = [x for x in station_df.index] if result_list is None else result_list
        else:
            result_list = selected_list

    return result_list


@app.callback(
    Output('all-graph', 'figure'),
    Input('station-dd', 'value'),
    State('all-graph', 'figure'))
def callback(new_selection, figure):
    if figure is None or new_selection is None or len(new_selection) == 0:
        selection_points = [x for x in station_df.index]
        if figure is not None:
            figure['data'][0]['selectedpoints'] = selection_points
        return make_all_graph(selection_points)
    elif figure['data'][0]['selectedpoints'] == new_selection:

        return figure
    else:
        selection_points = list(set(new_selection) | set(figure['data'][0]['selectedpoints']))
        figure['data'][0]['selectedpoints'] = selection_points
        return figure

def make_all_graph(selection=None):

    data = go.Scatter(x=station_df['x'],
                      y=station_df['y'],
                      customdata=station_df['customdata'],
                      mode='markers',
                      marker=dict(
                          size=14),
                      selectedpoints=selection,
                      marker_symbol='square',
                      text=station_df['customdata'],
                      hovertemplate='ID: %{text[0]}<br>' + 'Name: %{text[1]}<br>' +
                                    'Circuit: %{text[''2]}<br>' + 'Last Comm.: %{text[3]}<br>' +
                                    'Interval: %{text[4]}<br>' + 'Always Powered: %{text[5]}<br>' +
                                    'index: %{text[6]}<br>' + '<extra></extra>',
                      )

    layout = go.Layout(font=dict(family='Arial',
                                 size=14,
                                 color='dimgray'),
                       title=dict(text='Southern California Edison Satellite Stations',
                                  font=dict(family='Arial Narrow',
                                            size=20,
                                            color='dimgray')),
                       xaxis=dict(tickmode='array',
                                  tickvals=[0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50,
                                            55, 60, 65, 70, 75, 80, 85, 90, 95, 99],
                                  zeroline=False),
                       yaxis=dict(tickmode='array',
                                  tickvals=[20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30],
                                  ticktext=['2001 - 2099', '2100 - 2199', '2200 - 2299',
                                            '2300 - 2399', '2400 - 2499', '2500 - 2599',
                                            '2600 - 2699', '2700 - 2799', '2800 - 2899',
                                            '2900 - 2999', '3000 - 3099']),
                       legend=dict(orientation='h',
                                   yanchor='top',
                                   y=-0.1,
                                   xanchor='right',
                                   x=1),
                       hovermode='closest',
                       clickmode='event+select',
                       paper_bgcolor='#fff',
                       plot_bgcolor='#fff',
                       showlegend=True,
                       dragmode=False)

    fig = go.Figure(data=data, layout=layout)

    return fig

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start by reproducing the supplied callbacks add_to_dd, callback, and make_all_graph with the reported Dash and component versions. Trace selectedData, the dropdown value, and the figure's selectedpoints through clearing and a subsequent shift-click; done means the replacement selection is reflected consistently and the expected callback behavior occurs.

Written by the indexing model from the issue text.

Assessment

Tech stack
plotly, python
Domain
data-visualization, frontend
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
28/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.