I’ve succeeded by using a “tooltip dictionary” that will update the tooltip property of the hovertool to look for a different field/set of fields depending on widget state.
Rough example below with comments:
from bokeh.plotting import figure,show
from bokeh.layouts import column
from bokeh.models import CustomJS, HoverTool, Select, ColumnDataSource
f=figure()
#make two different renderers with two different datasources
fruit_src = ColumnDataSource(data={'x':[0,1,2],'y':[1,3,5],'fruit':['orange','apple','banana']})
veg_src = ColumnDataSource(data={'x':[2,3,1],'y':[2,1,4],'veg':['potato','broccoli','spinach']})
fruit_r = f.scatter(x='x',y='y',source=fruit_src,size=15)
veg_r = f.scatter(x='x',y='y',source=veg_src,visible=False,size=15)
#make a tooltip dictionary --> basically maps the select's value property to what you want the tooltips to point to
ttip_dict ={'Fruits':[('Fruit','@fruit')]
,'Veggies':[('Veggie','@veg')]}
#make a hovertool instance, initialized to trigger on the fruit renderer and get ttips from the Fruits key of ttip_dict
htool = HoverTool(renderers=[fruit_r],tooltips=ttip_dict['Fruits'])
f.add_tools(htool)
#make the select
sel = Select(value='Fruits',options=['Fruits','Veggies'])
#callback logic --> when the select value is Fruit, update the visibility of the two renderers, and alter the hovertool instance two ways:
#1) tell it to trigger on the appropriate renderer
#2) update its tooltips property to look for the appropriate field
cb = CustomJS(args=dict(fruit_r=fruit_r,veg_r=veg_r,sel=sel,htool=htool,ttip_dict=ttip_dict)
,code='''
if (sel.value=='Fruits'){
fruit_r.visible = true
veg_r.visible = false
htool.renderers = [fruit_r]
htool.tooltips=ttip_dict[sel.value]
}
else if (sel.value=='Veggies'){
fruit_r.visible = false
veg_r.visible = true
htool.renderers=[veg_r]
htool.tooltips=ttip_dict[sel.value]
}
''')
sel.js_on_change('value',cb)
show(column([f,sel]))