H3 Hexagonal Tile with click triggered updates on other figures

hey,

my aim is to have an interactive app served with proper map of city overlaid with hexagons. The idea is to interact with the hexagons and get them trigger some python code to update other bokeh figures to show data from the selected hexagons.

I have been spending the whole day for this, it would be great to get some input… I am confused right now on how to select the hexagons with mouse clicks… Could somebody more experienced show me path on related concepts and how to proceed.

For example, I got the concept of using

p.on_event(events.Tap, print_event(attributes=point_attributes))

where p is figure object. But one question I am having is how to figure out which hexagon was clicked…

cheers.

Hi bonobo2000!

It sounds like what you’re looking for is source.selected.indices. There’s a little bit of documentation here, but not a whole lot more than that. I looked through the examples directory for something like what you describe, but was surprised to come up relatively empty (i.e. this would be a good area for contributors to improve!).

If source.selected.indices doesn’t immediately get you what you need, please consider posting a minimal reproducing example of your code so that we can get a clearer picture and suggest specific tweaks.

thank you carolyn…

I managed to get me going using the source.selected.indices in the case of circles generated in a scatter plot…

here is my minimcal code that can detect click events on the circles. Note sure how to mark this up as code :frowning:

    from bokeh.events import ButtonClick, Tap
    from bokeh.models import Button
    from bokeh.layouts import column
    from bokeh.plotting import figure
    output_notebook()

    def bkapp(doc):
        button = Button()
        p      = figure(tools="pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select")
        
        source = ColumnDataSource(data={'x':[2, 5, 8],'y':[5, 8, 5]})
        circles = p.circle(x ='x', y = 'y', size = 30, source = source)
                
        def callback(attrname, old, new):
            print(attrname)
            print(old)
            print(new)
            print('Python:Click')

        source.selected.on_change('indices', callback)  # GOOD

        doc.add_root(column([button,p]))
        
    show(bkapp)        

Yet, I find it difficult to apply the same concept to arbitrary glyphs. I am drawing polygons “by hand”, on the figure, and it is not clear to me how to get the same event triggered. For example, see below, clicking on the triangles has no effect. It is the same code as above, but instead of using circle, I am using glyph:

from bokeh.events import ButtonClick, Tap
from bokeh.models import Button
from bokeh.layouts import column
from bokeh.plotting import figure
from bokeh.models.glyphs import Patch
output_notebook()

def bkapp(doc):
    button = Button()
    p      = figure(tools="poly_select,pan,wheel_zoom,zoom_in,zoom_out,reset,tap,lasso_select,box_select")
    
    source = ColumnDataSource(data={'x':[2, 5, 8],'y':[5, 8, 5]})
    glyph = Patch(x="x", y="y", fill_color="#a6cee3")
    p.add_glyph( source, glyph)
            
    def callback(attrname, old, new):
        print(attrname)
        print(old)
        print(new)
        print('Python:Click')

#     button.on_event(ButtonClick, callback)
#     source.on_change()

    source.selected.on_change('indices', callback)  # GOOD

    doc.add_root(column([button,p]))
    
show(bkapp)

@bonobo2000 hit testing is only supported on the “vectorized” glypys, i.e. on patches which draws multiple patches, then the selection indices will tell you which of those multiple patches was selected, just like with circles.

Hit testing is not currently supported on the “single” glyphs, e.g patch. harea, or varea. There is an issue to consider adding support but it is not a high priority at present

https://github.com/bokeh/bokeh/issues/9182

2 Likes

Thanks Bryan,
thanks to your tip I managed to do what I wanted, here is a screenshot…

1 Like