16

I have the following small example script making use of numpy and bokeh:

import numpy as np
import bokeh.plotting as bp
from bokeh.objects import HoverTool 
bp.output_file('test.html')

fig = bp.figure(tools="reset,hover")
x = np.linspace(0,2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)
s1 = fig.scatter(x=x,y=y1,color='#0000ff',size=10,legend='sine')
s1.select(dict(type=HoverTool)).tooltips = {"x":"$x", "y":"$y"}
s2 = fig.scatter(x=x,y=y2,color='#ff0000',size=10,legend='cosine')
s2.select(dict(type=HoverTool)).tooltips = {"x":"$x", "y":"$y"}
bp.show()

The problem is that the hover tool only works for the cosine curve but not for the sine.

I know that one option would be to plot both series togehter and change the color of the cosine data points:

import numpy as np
import bokeh.plotting as bp
from bokeh.objects import HoverTool 
bp.output_file('test.html')

fig = bp.figure(tools="reset,hover")
x = np.linspace(0,2*np.pi)

y1 = np.sin(x)
y2 = np.cos(x)

x = np.array([x,x]).flatten()
y = np.array([y1,y2]).flatten()

blue = np.array('#0000ff').flatten()
red = np.array('#ff0000').flatten()
colors = np.array([blue.repeat(len(y1)),red.repeat(len(y1))]).flatten()

s1 = fig.scatter(x=x,y=y,color=colors,size=10,legend='sine & cosine')
s1.select(dict(type=HoverTool)).tooltips = {"x":"$x", "y":"$y"}
bp.show()

But then I loose the legend entry for the second color.

How do I manage to be able to hover over both data sets and see the corresponding tooltip?

Thanks!

Max

Max
  • 335
  • 1
  • 3
  • 12

2 Answers2

33

Edit: Note that the approach below is necessary only if you want different tooltips for different glyphs. If you want the same tooltips for all glyphs, see the answer above.


If you want to have multiple hover tools, you need to add multiple hover tools, each configured for a different renderer. You can add them this way:

p = figure()

r1 = p.circle([1,2,3], [4,5,6], color="blue")
p.add_tools(HoverTool(renderers=[r1], tooltips=TIPS))

r2 = p.square([4,5,6], [1,2,3], color="red")
p.add_tools(HoverTool(renderers=[r2], tooltips=TIPS))
bigreddot
  • 33,642
  • 5
  • 69
  • 122
  • 2
    This should be added to the accepted answer. It is (as of now anyway) the correct way to set a different hover renderer per plot instead of per figure. – Peter Swords May 10 '18 at 02:10
  • 2
    This however causes the plot to have two different icons for "Hover". Is there a way to unify this (e.g. having a single icon to toggle both)? Alternatively, would it be possible to rename the "Hover" button to something more explicit? – norok2 Jul 04 '18 at 18:24
  • 1
    This is still an open issue: https://github.com/bokeh/bokeh/issues/5497 If you have the ability, please consider helping out and contributing. – bigreddot Jul 05 '18 at 18:01
14

The original answer was ancient and outdated, here is how to accomplish this with any modern version of Bokeh:

from bokeh.plotting import figure, show
import numpy as np

x = np.linspace(0, 2*np.pi)
y1 = np.sin(x)
y2 = np.cos(x)

fig = figure(tools="reset", tooltips=[("x", "$x"), ("y", "$y")])
s1 = fig.scatter(x, y1, color='#0000ff', size=10, legend_label='sine')
s2 = fig.scatter(x, y2, color='#ff0000', size=10, legend_label='cosine')

show(fig)
bigreddot
  • 33,642
  • 5
  • 69
  • 122
Damian Avila
  • 775
  • 8
  • 8
  • 5
    I got this error: AttributeError: 'generator' object has no attribute 'tooltips'. I updated my bokeh using this command: pip install --pre -i https://pypi.anaconda.org/bokeh/channel/dev/simple bokeh --extra-index-url https://pypi.python.org/simple/ – Hamid K Nov 05 '15 at 18:43
  • 1
    Same issue as Hamid on 0.10 – dranxo Nov 30 '15 at 04:07
  • The tool is on *figure*: Need to do: `fig.select(HoverTool)` – bigreddot Dec 30 '15 at 18:19
  • `AttributeError: 'generator' object has no attribute 'tooltips'` – Coddy Jul 29 '20 at 23:36
  • This answer is ancient, and the library has changed and improved considerably in six years since this was posted. None of the `select` business is necessary at all for basic tooltips. I have updated the answer to reflect modern usage. – bigreddot Jul 29 '20 at 23:46