Sascha
Sascha

Reputation: 219

Using multiple bokeh HoverTool instances together with the models API

I'd like to use multiple Hovertools in one plot together with Hovertool's names attribute to selectivly apply each tool. Take for instance

hover1 = HoverTool(tooltips=[("group", "1")], names = ['line1'])
hover2 = HoverTool(tooltips=[("group", "2")], names = ['lines2'])

and the two data sources:

source1 = ColumnDataSource(data=dict(
xs=[[1, 3, 2], [3, 4, 6, 6]],
ys=[[2, 1, 4], [4, 7, 8, 5]], 
))

source2 = ColumnDataSource(data=dict(
xs=[[1, 3, 2], [6, 7, 9, 8]],
ys=[[-1, 0, 1], [1, 1, 2, 1]]
))

I'd though the following (using the bokeh.models API) should do what I want

p = figure(plot_width=400, plot_height=400)
l1 = MultiLine(xs='xs', ys='ys', name='lines1')
l2 = MultiLine(xs='xs', ys='ys', name='lines2')
p.add_tools(hover)
p.add_tools(hover2)
p.add_glyph(source1, l1)
p.add_glyph(source2, l2)
show(p)

Alas the Hovertools in the resulting plot do not work (i.e. no tooltips are shown). Using the bokeh.plotting API as follows and everything works as expected:

p = figure(plot_width=400, plot_height=400, tools=[hover, hover2])
p.multi_line(xs='xs', ys='ys', source=source1, name='lines1')
p.multi_line(xs='xs', ys='ys', source=source2, name='lines2')
show(p)

Question: How does one replicate the result of the bokeh.plotting API with the bokeh.models API?

Upvotes: 1

Views: 2734

Answers (1)

ChesuCR
ChesuCR

Reputation: 9640

The names attribute of the HoverTool model in the Bokeh Documentation:

names: property type: List ( String )

A list of names to query for. If set, only renderers that have a matching value for their name attribute will be used.

With this

l1 = MultiLine(xs='xs', ys='ys', name='lines1')

You are assigning the name to the Multiline object and that is a glyph, not a renderer. So try this instead

from bokeh.io import output_notebook, show
output_notebook()

import numpy as np
from bokeh.plotting import figure
from bokeh.models.sources import ColumnDataSource
from bokeh.models.glyphs import MultiLine
from bokeh.layouts import row
from bokeh.models.tools import HoverTool

source = ColumnDataSource(data=dict(
        xs1=[[1, 2, 3], [5, 6, 7]],
        ys1=[[1, 2, 3], [6, 5, 7]],
        xs2=[[7, 8, 9], [1, 2, 3]],
        ys2=[[4, 5, 7], [6, 7, 2]],
    )
)

hover1 = HoverTool(tooltips=[("group", "1")], names = ['lines1'])
hover2 = HoverTool(tooltips=[("group", "2")], names = ['lines2'])

p = figure(plot_width=400, plot_height=400)
l1 = MultiLine(xs='xs1', ys='ys1')
l2 = MultiLine(xs='xs2', ys='ys2')
r1 = p.add_glyph(source, l1, name='lines1')  # the name is assigned to the renderer
r2 = p.add_glyph(source, l2, name='lines2')
# r1.name = 'lines1'  # or you could assign the name like this as well
# r2.name = 'lines2'

p.add_tools(hover1)
p.add_tools(hover2)

# p = figure(plot_width=400, plot_height=400, tools=[hover1, hover2])
# p.multi_line(xs='xs1', ys='ys1', source=source, name='lines1')
# p.multi_line(xs='xs2', ys='ys2', source=source, name='lines2')


show(p)

Upvotes: 5

Related Questions