"selected-data" that is not tied to points in a graph

In the graph crossfilter example from https://plot.ly/dash/getting-started-part-2, we can see that we have access to hover data, click data, and selection data.

What these three data elements have in common is that they are tied to points in the graph. This means that if you select a region that has no points, then selectData will be empty.

Is there a way to capture the region selected, whether or not points are contained within? The Box Select corner coordinates would be nice to have. For the Lasso select, this would be a little more complicated.

Is this something that Plotly already supports?

I want to be able to select an arbitrary subset of points, and then display statistics about these points, such as a histogram. There is a nice dashboard example out there using a dataset called “flights and conflicts 2008-2009” or something like that. But here “dashboard” means Plotly dashboard, not Dash dashboard.

There is a nice dashboard example out there using a dataset called “flights and conflicts 2008-2009” or something like that.

Do you mean this? jQDateRangeSlider (default ctor) - JSFiddle - Code Playground

Why yes, that is the one I am talking about. Nice graph!

In that plot, when you zoom in, the histograms update.

I’d like to know if there is a way to do something similar in dash, but without having to zoom in. I want to keep all the points visible, but with the default shaded effect, which is nice.

Let me be more specific.

I have a scatter plot with a slider. I want to be able to slice the dataset in two ways:

  1. By selecting points either with the lasso or the select box.
  2. By indexing the data array from 0 to the slider value. The index is a custom data point, could be date as in your flights-conflicts graph.

The sliced data is then represented in a histogram.

Here is my callback for the histogram update:

@app.callback(
    Output('mydata-hist','figure'),            # The histogram
    [Input('mydata-scatter', 'selectedData'),  # The scatter plot -- slice by selection
    Input('mydata-slider', 'value')])          # The slider -- slice by an index
def update_hist(selectedData,sliderVal):
    if sliderVal is None:
        sliderVal = 0

    if selectedData:
        dats = selectedData['points']
        points = [dats[x]['pointNumber'] for x in range(0,len(dats))]
        sliced_x = [mydata[x] for x in points]
    else:
        sliced_x = mydata[0:sliderVal]
    figure={
        'data': [go.Histogram(x=sliced_x, orientation='v', histnorm='probability')],
        'layout': go.Layout(xaxis={'type':'linear'},
                            yaxis={'type':'linear'},
                            )
    }
    return figure 

Do you see the problem with this code? I can only slice in one direction at a time (slider or selection)

I can get a partial solution with this callback, by first selecting, and then slider-ing. But then each time I use the slider, I have to reset the selection so that the histogram updates.

I guess you can also view problem from the histogram perspective. Imagine the scatter plot has a sparse region with only one point. If I select a really large area around that one point, then my histogram is just going to look like a fat rectangle.

But if I had access to the entire selection area, then I could adjust the start and end bins, as well as the bin size, so that the histogram would look like a single skinny bar with a wide 0-valued range on either side. I could also place the location of that single skinny bar at its natural position, which would again be relative to the original selection on the scatter plot.

Great suggestion @alex_01! This ended up being an easy addition so I just added in this PR: https://github.com/plotly/dash-core-components/pull/33

You can upgrade with pip install dash-core-components==0.5.3. The docs have been updated as well:

2 Likes

Thanks. Dash team is awesome!!

1 Like

I like how the selected points under lasso selection is not just the range, but the actual boundary drawn by the cursor.

1 Like

Would it be just as easy to implement a way that clickData is not NULL if one clicks an empty space in a graph?
The return value could just be the x/y coordinates instead of the dictionary, defining the point one clicks?