I want to use hovertool in my appliation.
hovetool doesn’t work for vbar drawn in periodic_calback,
while it works for vbar drawn at first.
Here is my code.
from bokeh.plotting import figure, curdoc
from bokeh.models import HoverTool
n_callback = 0
seq_no = 0
def draw_vbar(color):
global seq_no
bottom_data_list = accum_data_list.copy()
for i in range(15):
accum_data_list[i] += 10
vbar = fig_p.vbar(x=idx_list, width=0.9, top=accum_data_list.copy(), bottom =bottom_data_list,color=color)
vbar.data_source.data["seq_no"] = [seq_no for i in range(15)]
seq_no += 1
def update():
global n_callback
print(n_callback)
if n_callback == 0:
draw_vbar("green")
n_callback += 1
idx_list = [i for i in range(1,16)]
accum_data_list = [0 for i in range(15)]
hv_tool = HoverTool()
hv_tool.tooltips=[("Sequence No.","@seq_no")]
fig_p = figure(title="HoverToolTest",x_range=(0.5,15.5))
fig_p.add_tools(hv_tool)
draw_vbar("blue")
draw_vbar("yellow")
curdoc().add_root(fig_p)
curdoc().add_periodic_callback(update,1000)
HoverTool shows “Sequence No:0” for blue vbar and “Sequence No:1” for yellow vbar. However, it doesn’t show anything for green vbar.
How can I tell HoverTool that new vbar is added to the figure?
I used bokeh 2.0.2 and python 3.6.9 on Ubuntu 18.04.
I used Chrome 81.0.4044.138 and FireFox 76.0.1, HoverTool didn’t work for green vbar in both browser.
I run this application like “bokeh serve thiscode.py”
HoverTool has a list of renderers that it works on. If you provide no renderers, by default it will use all the existing ones. If you add new renderers to a hover tool that you want it to work on, be sure to update its renderers property as well.
To add to @p-himik’s response: I ran into a similar situtation recently in a project I’m working on, where a large number of new renderers were added to the plot with each update.
I found it simplest to delete the existing hovertool from the plot’s tools list and re-create it with each call of the callback.
Hi @p-himik. Thank you for your very quick response.
Although I added renderer to hover_tool.renderers using “hv_tool.renderers.append(vbar)”, hovetool still doesn’t work for green vbar.
Did I misunderstand what you told me?
from bokeh.plotting import figure, curdoc
from bokeh.models import HoverTool
n_callback = 0
seq_no = 0
def draw_vbar(color):
global seq_no
bottom_data_list = accum_data_list.copy()
for i in range(15):
accum_data_list[i] += 10
vbar = fig_p.vbar(x=idx_list, width=0.9, top=accum_data_list.copy(), bottom =bottom_data_list,color=color)
vbar.data_source.data["seq_no"] = [seq_no for i in range(15)]
hv_tool.renderers.append(vbar) #add renderer
print(hv_tool.renderers)
seq_no += 1
def update():
global n_callback
print(n_callback)
if n_callback == 0:
draw_vbar("green")
n_callback += 1
idx_list = [i for i in range(1,16)]
accum_data_list = [0 for i in range(15)]
hv_tool = HoverTool()
hv_tool.tooltips=[("Sequence No.","@seq_no")]
hv_tool.renderers = [] # to avoid renderers to be "auto"
fig_p = figure(title="HoverToolTest",x_range=(0.5,15.5))
fig_p.add_tools(hv_tool)
draw_vbar("blue")
draw_vbar("yellow")
curdoc().add_root(fig_p)
curdoc().add_periodic_callback(update,1000)
Hi @carolyn. Thank you for proposing another solution kindly.
Following code works well. I appriciate for sharing your experience with us.
from bokeh.plotting import figure, curdoc
from bokeh.models import HoverTool
n_callback = 0
seq_no = 0
hv_tool = None
def draw_vbar(color):
global seq_no
global hv_tool
bottom_data_list = accum_data_list.copy()
for i in range(15):
accum_data_list[i] += 10
vbar = fig_p.vbar(x=idx_list, width=0.9, top=accum_data_list.copy(), bottom =bottom_data_list,color=color)
vbar.data_source.data["seq_no"] = [seq_no for i in range(15)]
if seq_no != 0:
fig_p.toolbar.tools.remove(hv_tool) #delete old hover tool
hv_tool = HoverTool() #recreate hover tool
hv_tool.tooltips=[("Sequence No.","@seq_no")]
fig_p.add_tools(hv_tool) #add new hover tool
seq_no += 1
def update():
global n_callback
print(n_callback)
if n_callback == 0:
draw_vbar("green")
n_callback += 1
idx_list = [i for i in range(1,16)]
accum_data_list = [0 for i in range(15)]
fig_p = figure(title="HoverToolTest",x_range=(0.5,15.5))
draw_vbar("blue")
draw_vbar("yellow")
curdoc().add_root(fig_p)
curdoc().add_periodic_callback(update,1000)
Your code seems fine to me but maybe there’s some Bokeh “plumbing” missing. I would also try hv_tool.renderers = hv_tool.renderers + [vbar]. But since carolyn’s solution works for you then it’s all good either way.