Separate tooltips for separate traces in one graph

I want to create a graph that shows to data series (traces), one blue one red in combined line+scatter plot. I think I found out how to do this.

However I would also like hover information to be shown for the data points in that plot. If the cursor is on a datapoint from the first (red) trace, the x/y values for that data point should be shown, and if it is on a data point from the other trace, the information for that point should get shown.

However, I could not find out how to do this because the tooltip cannot be defined per trace but only for the plot containing those traces.

The closest I got is the code shown below which seems to show ALL y values from from all the traces in the hover information.
This is easy to do with Plotly, because the hover/tooltip information can be specified for each trace separately before combining the traces into the same plot.

Am I missing the proper way for how to do this in Bokeh?

(Using “$y” in place of “@y1” and “@y2” makes it impossible to show the name of the variable/trace selected which is important with crowded data)

import bokeh
print("bokeh", bokeh.__version__)
import bokeh.io
import bokeh.plotting
import numpy as np
import notebook, IPython, jupyter, jupyter_bokeh
print("notebook", notebook.__version__, "IPython", IPython.__version__, "jupyter", jupyter.__version__, jupyter_bokeh.__version__)
bokeh.io.reset_output()
bokeh.io.output_notebook()
TOOLTIPS = [
    ("x", "$x"),
    ("y1", "@y1"),
    ("y2", "@y2"),
]

x1=np.arange(0,100,5)
x2=np.arange(0,100,5)+2
y1=np.random.randn(20)
y2=np.random.randn(20)
data={
    "x1": x1,
    "x2": x2,
    "y1": y1,
    "y2": y2,
}
source = bokeh.models.ColumnDataSource(data=data)
xdr = bokeh.models.Range1d(start=0, end=99)
fig = bokeh.plotting.figure(height=300, width=800,
                           tools="xpan,box_zoom,wheel_zoom,xbox_select,reset", toolbar_location="above",
                           tooltips=TOOLTIPS,
                           x_axis_location="above", x_range=xdr)
fig.line('x1', "y1", source=source, color="red")
fig.scatter('x1', "y1", source=source, color="red")
fig.line('x2', "y2", source=source, color="blue")
fig.scatter('x2', "y2", source=source, color="blue")

bokeh.plotting.show(fig)

This is not true. You are currently using the highest level convenience API which trades ease of use (i.e. “no code”, just pass a single tooltips list) for functionality. You can add as many HoverTool instances, and you like and you can configure the renderers property of each HoverToool instance to restrict it to whatever glyph or subset of glyphs you like. See e.g. this example:

There are a number of examples under the example directory that demonstrate using HoverTool directly.

1 Like

Thanks a lot! I have adapted my code with your suggestion and it seems to work perfectly. The updated code is

import bokeh
print("bokeh", bokeh.__version__)
import bokeh.io
import bokeh.plotting
import numpy as np
import notebook, IPython, jupyter, jupyter_bokeh
from bokeh.models import HoverTool
print("notebook", notebook.__version__, "IPython", IPython.__version__, "jupyter", jupyter.__version__, jupyter_bokeh.__version__)


bokeh.io.reset_output()
bokeh.io.output_notebook()
TOOLTIPS1 = [
    ("x", "$x"),
    ("y1", "@{y1.v}"),
]
TOOLTIPS2 = [
    ("x", "$x"),
    ("y2", "@{y2.v}"),
]

x1=np.arange(0,100,5)
x2=np.arange(0,100,5)+2
y1=np.random.randn(20)
y2=np.random.randn(20)
data={
    "x1": x1,
    "x2": x2,
    "y1.v": y1,
    "y2.v": y2,
}
source = bokeh.models.ColumnDataSource(data=data)
xdr = bokeh.models.Range1d(start=0, end=99)
fig = bokeh.plotting.figure(height=300, width=800,
                           tools="xpan,box_zoom,wheel_zoom,xbox_select,reset", toolbar_location="above",
                           x_axis_location="above", x_range=xdr)
fig.line('x1', "y1.v", source=source, color="red")
r1 = fig.scatter('x1', "y1.v", source=source, color="red")
fig.add_tools(HoverTool(tooltips=TOOLTIPS1, mode="mouse", point_policy="follow_mouse", renderers=[r1]))
fig.line('x2', "y2.v", source=source, color="blue")
r2 = fig.scatter('x2', "y2.v", source=source, color="blue")
fig.add_tools(HoverTool(tooltips=TOOLTIPS2, mode="mouse", point_policy="follow_mouse", renderers=[r2]))

bokeh.plotting.show(fig)
1 Like

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.