Figure Axis Callback

Bokeh 2.1.0.
Is there a way to get callback when user clicks axis? The documentation led me in this direction (below), but none of the callbacks triggered. Minimal example,

from bokeh.layouts import layout
from bokeh.io import show
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.events import ButtonClick, Tap, DoubleTap, Press, MouseEnter

source = ColumnDataSource(data={
    "t":  [0,  1,  2,  3, 4],
    "i":  [1, 10, 20, 30, 40],
})

plot = figure(toolbar_location="above", y_range=(0, 50), x_range=(0, 5))

line = plot.line(x="t", y="i", line_width=2, source=source, color="green", legend_label="SRC")

callback = CustomJS(code="console.log('tap event occurred')")
plot.yaxis.js_on_event(Tap, callback)
plot.yaxis.js_on_event(ButtonClick, callback)
plot.yaxis.js_on_event(DoubleTap, callback)
plot.yaxis.js_on_event(Press, callback)
plot.yaxis.js_on_event(MouseEnter, callback)

doc_layout = layout()
doc_layout.children.append(plot)

show(doc_layout)

There is not currently any built-in mechanism. It could be potentially accomplished with a custom extension. But built-in events currently only respond inside the "plot frame. There are two relevant open issues:

Thanks.

As a possible work-around perhaps one can use the sx/sy co-ordinates from a tap event from the plot. For my purposes, for example, I think I can use those values to know the user is selecting the left y-axis, sx will be a small number.

@Martin_Guthrie

Conceptually, another option that might work is …

  1. Add a glyph like a line, line segment, area, patch, or whatever that covers the axis of interest. Set the alpha property(ies) to 0.0; it will be visible to the software and interactions but invisible/transparent to the user.

  2. Add a tap tool with the above-mentioned glyph renderers and a callback that does whatever is needed when that glyph is clicked on / selected.

I tried the idea mentioned, but no events… code,

from bokeh.layouts import layout
from bokeh.io import show
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, CustomJS
from bokeh.events import Tap, DoubleTap, Press, MouseEnter
from bokeh.models.glyphs import Line

source = ColumnDataSource(data={"t":  [0,  1,  2,  3, 4], "i":  [1, 10, 20, 30, 40]})

plot = figure(toolbar_location="above", y_range=(0, 50), x_range=(0, 5))

myglyph = Line(x="t", y="i", line_color="red", line_width=10)
callback = CustomJS(code="console.log('tap event occurred')")
myglyph.js_on_event(Tap, callback)
#myglyph.js_on_event(Press, callback)
#myglyph.js_on_event(MouseEnter, callback)
#myglyph.js_on_event(DoubleTap, callback)
plot.add_glyph(source, myglyph)

doc_layout = layout()
doc_layout.children.append(plot)

show(doc_layout)

@Martin_Guthrie

Sorry for the confusion. You need to add a TapTool and register a callback to deal with the glyphs that get selected by the user interactively clicking on them when the TapTool is active.

The events you have currently in your code are associated with the plot area as mentioned in the reply from @Bryan.

If that’s overly complicated for your use case, your idea about looking at the units (either in data space or screen space) seems like a good one to know if the user clicks in an acceptable vicinity of the axis.