I try to make a JSCallback for a line and access the index of it.
For the circle()
glyph, this works if I precisely hover over the dot. In this case, the Hover annotation works and the cb_data['index'].indices
holds the same value as the hover annotation shows. However, for the line()
with mode='vline'
, this does not work. Even when the internal hover annotation shows an index, the cb_data['index'].indices
is empty.
Below is a minimal working example that shows this case in the console log of the browser:
import pandas as pd
from bokeh.plotting import figure, curdoc
from bokeh.models import ColumnDataSource, HoverTool, CustomJS
from bokeh.layouts import layout
plot1 = figure(plot_width=1000, plot_height=250)
plot2 = figure(plot_width=1000, plot_height=250)
df = pd.DataFrame({"ID":[0, 1, 2, 3, 4, 5, 6, 7],
"Value1":[0, 100, 200, 300, 400, 500, 600, 700],
"Value2":[0, 1, 2, 4,8 , 16, 32, 64]})
source = ColumnDataSource(df)
line = plot1.line(x='ID', y='Value1', source=source)
circle = plot2.circle(x='ID', y='Value2', source=source)
callback = CustomJS(args=dict(source=source),
code="""
console.log("Indices: "+ cb_data['index'].indices);
console.log("Mouse X: "+ cb_data['geometry'].x);
console.log("Mouse Y: "+ cb_data['geometry'].y);
""")
hover_tool_plot = HoverTool(mode='vline', callback=callback)
plot1.add_tools(hover_tool_plot)
plot2.add_tools(hover_tool_plot)
layout_ = layout([[plot1],[plot2]])
curdoc().add_root(layout_)
When I hover between the two points 5 and 6, the hover annotation snaps to the index 6. However, the output looks as follows, which means there is no index selected:
Indices:
VM612:6 Mouse X: 5.642537313432836
VM612:7 Mouse Y: 469.12556053811653
For the circle case, this does work (But as I said, only if I hover exactly over the point). The output of the log indeed gives me the index 6.
Indices: 6
VM746:6 Mouse X: 5.995974576271187
VM746:7 Mouse Y: 32.473542600896856
Is there any way to get the correct index when hovering over the line using the mode='vline'
?
I do need the index in the callback to set a line in another plot for my application.
PS: I´m running Bokeh as a server application.
For a line glyph, you want to look at .line_indices
, not .indices
.
Note that there is no one "correct" answer about which index (previous? next? nearest?) should be returned. The hover tool has a line_policy
setting that you can customize you your needs.