☰Read-only archive⌕
Looking for help with Bokeh?

This is a read-only archive. Ask questions and join the conversation on GitHub.

Visit Community Support on GitHub →
Archived discussions · Captured October 28, 2026

Data on tap tool event/cb

Community Support
rmitchel
rmitchel

I’m encountering an issue with a dissonance between what the TapTool registers versus what is selected on the CDS. With the following code:

taptool = figure.select(type=TapTool)
    taptool.callback = CustomJS(args=
                                dict(),
                                code=cb)

Where cb is:

    data = cb_data.source.data;
    console.log("clicked");
    console.log(cb_data.source.selected.indices);
    item = data.cl[cb_data.source.selected.indices[0]];
    if(item != undefined) {
        // do something
    }

Most of the time, a click (on a point on the figure) is registered, but selected is empty! I have to be hovering perfectly over it in order for selected and TapTool to agree. Am I accessing data from the wrong selected var?

Thanks,
Ryan

⌁   Link to post
Bryan
Bryan

This may just be an order of operations concern. Things have to happen in some order, and offhand I have no idea if there’s any reason to suspect whether the CDS selection must be set before or after a tap tool callback is executed. A complete small example would be useful to do some quick investigation.

⌁   Link to post
rmitchel
rmitchel

Ah ok, happy to make one, but then are you saying that checking the ‘selected’ is the correct way of figuring out what was tapped? It seems weird to me that the taptool is capable of only activating when a glyph is clicked, yet it isn’t capable of providing the data/index that glyph represents.

Best,
Ryan

⌁   Link to post
rmitchel
rmitchel

Alright, this produces “failed” (which given it’s inside a taptool callback, shouldn’t happen)

from bokeh.document import Document
from bokeh.io import curdoc
from bokeh.models import ColumnDataSource, TapTool, CustomJS
from bokeh.plotting import figure
import pandas as pd

# ------------------ Data Prep ------------------ #
doc = curdoc()
args = doc.session_context.request.arguments

p = figure(tools="tap,save",
           background_fill_color='gray', background_fill_alpha=0.3,
           match_aspect=True, plot_height=500, plot_width=2000)
df = pd.DataFrame({"x": [1, 2, 3, 4, 5], "y": [1, 2, 3, 4, 5]})

source = ColumnDataSource(df)

line = p.line(x="x", y="y", source=source,
              alpha=1.0)
circle = p.circle(x="x", y="y", source=source)

taptool = p.select(type=TapTool)
taptool.callback = CustomJS(args=
                            dict(),
                            code=
                            """
data = cb_data.source.data;
val_x = data.x[cb_data.source.selected.indices[0]];
val_y = data.y[cb_data.source.selected.indices[0]];
if(val_x != undefined && val_y != undefined) {
    console.log("something clicked" + " x: " + val_x + ", y: " + val_y);    
}
else {
    console.log("failed");
}
              """)

doc.add_root(p)

Can just bokeh serve it!

⌁   Link to post

End of archived discussion · Replies are disabled