☰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

Python callback for HoverTool

Community Supporthoverserver
agilly
agilly

Hi all,

I am currently upgrading my bokeh app from 0.12 to the most recent version, and have decided to switch to a server implementation. I have a side panel with lots of controls that allow to tweak the plot, these used to be managed cumbersomely using quite large CustomJS callbacks. I am now rewriting them into python callbacks. For Button or RadioButtonGroup there is the on_click function which allows to do:

UI_item=RadioButtonGroup(...)
def callback_UI_item(active):
    #callback code here
UI_item.on_click(callback_UI_item)

My question is, how do I do the same for a HoverTool? In particular, I would like to do something like this, but it gives me an error (ValueError: expected an instance of type Callback, got <function callback_hover at 0x7fc9aa44c7b8> of type function):

p1=figure(...)
main_dataset=p1.circle(..., source=data_source)

def callback_hover(cb_data):
	print(cb_data.Index)

hovertool=HoverTool(callback=callback_hover, renderers=[main_dataset])
p1.add_tools(hovertool)

TIA

⌁   Link to post
p-himik
p-himik

The docstring for HoverTool.callback says: “A callback to run in the browser whenever the input’s value changes.”. The crucial part is “in the browser”, so you have to use a subclass of Callback (most often it’s CustomJS) and you can’t trigger Python functions with it. Well, not directly - you could use e.g. some ColumnDataSource created just for that and use it to notify the backend about the hover.

⌁   Link to post
agilly
agilly

Thanks. Can you tell me more about your intermediate ColumnDataSource solution? Do you mean to initialise it as empty, fill it with hover data using a CustomJS callback, and then adding a python callback to that source? If yes, I think I got it except for the very last step, how would I add a callback to a ColumnDataSource to trigger on data change?

⌁   Link to post
Gilles
Gilles

Does the datasource needs to be attached to a renderer?

I tried to implement the above solution but I do not get the server callback when the datasource is updated. The CustomJs callback get triggered and the datasource is updated. This is part of the code I used:

hover_details_data_source = ColumnDataSource(
{
‘indices’:
}
)
hover_details_data_source.on_change(‘data’, on_hover_callback)

code = “”"
console.log('indices: ’ + cb_data.index.indices)
const indices = cb_data.index.indices
if (indices.length){
data_source.data[‘indices’] = cb_data.index.indices
data_source.change.emit();
}
“”"
callback = CustomJS(
args={
‘data_source’: hover_details_data_source
},
code=code
)

hover = plot.select(“hover”)
hover.callback = callback

def on_hover_callback(attr, old, new):
print(‘Here’)

⌁   Link to post
Bryan
Bryan

@Gilles please open a brand new question topic, and please make sure to use code formatting so that the code is intelligible (either with the </> icon on the editing toolbar, or triple backtick ``` fences around the code blocks)

⌁   Link to post

End of archived discussion · Replies are disabled