Is it possible to use lasso_select in rect?

Hi all,

I’ve been developing a heatmap-based interactive dashboard application.
Anyway, the most important feature of my project is selecting various regions on the heatmap.

I tried an official example of lasso_selection here.
And to make a heatmap, I use the official example too.

Then through my foolish idea, just change the glyph object (circle → rect) and combine both examples properly, it could work.
But It doesn’t work. What I tried is below.

p1 = figure(plot_width=500, plot_height=500, title="Select Here",
            x_range=None, y_range=None,
            toolbar_location='below', tools="wheel_zoom, pan, save, lasso_select", x_axis_location="above", output_backend = 'webgl')

p1.rect(x="X", y="Y", width=1, height=1, source=s1,
        line_color=None, fill_color=transform('rate', mapper))

s2 = ColumnDataSource(data = dict(X = [], Y = []))
p2 = figure(width=500, height=500, title="Watch Here", tools ='wheel_zoom',
            x_range=None, y_range=None, toolbar_location='below', output_backend = 'webgl')

p2.rect(x="X", y="Y", width=1, height=1, source=s2,
        line_color=None, fill_color='blue')

p2.axis.visible = False

columns = [TableColumn(field ="X",  title = "X axis"),
           TableColumn(field ="Y",  title = "Y axis")]

table = DataTable(source =s2, columns = columns, width =155, height = 380)

s1.selected.js_on_change('indices', CustomJS(args=dict(s1=s1, s2=s2, table=table), code="""
        var inds = cb_obj.indices;
        var d1 = s1.data;
        var d2 = s2.data;
        d2['X'] = []
        d2['Y'] = []

        for (var i = 0; i < inds.length; i++) {
            d2['X'].push(d1['X'][inds[i]])
            d2['Y'].push(d1['Y'][inds[i]])
        }
        s2.change.emit();
        table.change.emit();
    """)
                         )

s2.selected.js_on_change('indices', CustomJS(args=dict(s1=s1, s2=s2, table=table), code="""
        console.log("TEST!");
        var inds = cb_obj.indices;
        var d1 = s1.data;
        var d2 = s2.data;
        d2['X'] = []
        d2['Y'] = []
        for (var i = 0; i < inds.length; i++) {
            d2['X'].push(d1['X'][inds[i]])
            d2['Y'].push(d1['Y'][inds[i]])
        }
        s2.change.emit();
        table.change.emit();
    """)
                         )

Is the selection impossible for rect()? (Especially, for heatmap)
To verify whether CustomJS() function does work, I use console.log().
Then I find that CustomJS() is not working for rect().
(In other figures, such as circle or square, I can see the log and lasso_select are working for the same code.)

And when I use select tools in other glyph objects, I can use them, which means there are some changes.
But in the rect, there are nothing changes when I choose the select tools.
So, on the heatmap, there is no way to use select tools?

Few people seem to want to use select tools in the heatmap.
The closest question I found this.
→ Correct way to use Selection (Lasso, Box) on an Image (By kaprisonne, Apr '21)
(Regarding the limitation of the max number of hyperlink-text for a new user, I attached a topic name and author. Sorry for inconvenient)

Is there a similar problem with the rect() object?

Thanks everyone!

It’s because with a Rect, or a Quad or Patches for that matter, there is extra nuance to selection. Do you want it to be “greedy” i.e. select if lasso covers any part of the Rect? Or do you want it to be the opposite i.e. select only if lasso covers the entire Rect? Or do you want selection only if the Rect’s centre is covered? Or do you want a selection once 50% or more of the Rect’s area is covered?

What I’ve done in the past is simply to plot a scatter “underneath” the rect, driven by the same source using the Rect’s centroid columns. Make that scatter have a fill_alpha and line_alpha of 0 for both selection and non_selection glyphs, and make that scatter renderer be the thing that is selectable. That will grant you the ability to select Rects based on the lasso select including their centroid (i.e. only one of the above possibilities).

2 Likes

Rect glyph doesn’t implement polygonal hit testing (only point and rect), which is required by lasso selection tool, so it isn’t going to work currently.

1 Like

FYI what glyphs support what hit-testing is presented in a table here:

1 Like

Thank you, gmerritt123! That’s brilliant!

I think of a similar idea that using an invisible scatter plot, but don’t know how to exactly do it.

After seeing your great comment, I think linking could be one of the solutions. Thank you again for your detailed answer.

Thank you, mateusz!

What I worried was right… I’ll try another way!