I'm a bit vexed with the HoverTool in Bokeh. I've got a ColumnDataSource that has multiple data 'columns' and I use the various columns to plot lines on a graph. When I hover on one of the points on a line, I want to show the 'x' ('rpm' data in my CDS) and 'y' (one of the other columns in my CDS) data for that point on that line.
Since all lines are using the same CDS (different columns for 'y' values), for the life of me, I can't figure out how to discriminate the 'y' value for the line being hovered on, and display only the 'y' value for that line. Currently, I'm just displaying all of the 'y' values for the 'x' value being hovered on.
I don't want to use the '$y' parameter, because that's just the location of the cursor on the graph, not the data for the hovered point.
Would appreciate your thoughts. Thanks.
Note, this program plots vehicle speed for given engine RPM, and each series is by transmission gear.
import itertools
from bokeh.plotting import figure, show
from bokeh.models import ColumnDataSource, HoverTool
from bokeh.palettes import Category20_20 as palette
data={'rpm': range(2000, 4000, 500),
'1st': [15.00040961597459,
18.750512019968237,
22.50061442396188,
26.25071682795553],
'2nd': [28.241511931310182,
35.301889914137725,
42.36226789696527,
49.422645879792825],
'3rd': [45.751249328722494,
57.18906166090312,
68.62687399308373,
80.06468632526436],
'4th': [66.30615844742391,
82.8826980592799,
99.45923767113587,
116.03577728299183]}
cds = ColumnDataSource(data=data)
fig = figure(width=800, height= 600, title='Speed', x_axis_label='RPM', y_axis_label='Speed(mph)')
hovertools= HoverTool(tooltips=[('Gear', '$name'),
('4th', '@4th{0.0}'),
('3rd', '@3rd{0.0}'),
('2nd', '@2nd{0.0}'),
('1st', '@1st{0.0}'),
('RPM', '@rpm')],)
colors = itertools.cycle(palette)
fig.add_tools(hovertools)
for gear in ('1st', '2nd', '3rd', '4th'):
color = colors.__next__()
fig.line(x='rpm',
y=gear,
source=cds,
color=color,
legend=gear + ' gear',
muted_color=color,
muted_alpha=0.2,
line_width=1,
name=gear + ' gear')
fig.circle(x='rpm',
y=gear,
source=cds,
color=color,
legend=gear + ' gear',
muted_color=color,
muted_alpha=0.2,
line_width=1,
name=gear + ' gear')
fig.legend.click_policy = "mute"
fig.legend.background_fill_alpha = 0.5
show(fig)
You can use @$name to look up the value of the column that has $name as the column name:
hovertools= HoverTool(tooltips=[('Gear', '$name'),
('data', '@$name{0.0}'),
('RPM', '@rpm')],)
But note, for this to work, the value you set for name in the glyph method has to match the column name. E.g. I had to change:
for gear in ('1st', '2nd', '3rd', '4th'):
color = colors.__next__()
fig.line(x='rpm',
y=gear,
...
name=gear) # CHANGED to match column name
fig.circle(x='rpm',
y=gear,
...
name=gear) # CHANGED to match column name
This yields:


Note that in the "tuple" format for tooltips, the first label value is not expaned, so if you want e.g. something like 4th gear: <value> on a per-line basis, then you'll want to use a Custom Tooltip
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With