Bokeh: 在联动图中同步悬停工具提示

7
我有两个关联的图表。当鼠标悬停时,我希望在两个图表中都出现工具提示。我已经非常成功地使用了链接选择,但现在我也想链接工具提示。
下面是一个示例。工具提示出现在左侧图表中。如果可以在右侧图表中也出现相应的工具提示就太好了。相应的数据点是具有相同ID的数据点。(存在共享的3D列数据源;每个图表都采用不同的2D视图)。

enter image description here

附注:我会改进工具提示文本。

更新

最终得出了以下内容:

enter image description here

2个回答

6
有点晚了,但这是我的解决方案,如果有人想知道的话:
from bokeh.io import curdoc
from bokeh.layouts import row
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, HoverTool, CustomJS

x = list(range(-20, 21))
y0 = [abs(xx) for xx in x]
y1 = [xx**2 for xx in x]

# can be either the same source for all plots or different sources (as shown here) but the length of the sources should be the same
source1 = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1))
source2 = ColumnDataSource(data=dict(x=x, y0=y0, y1=y1))
code1 = "source1.set('selected', cb_data['index']);"
code2 = "source2.set('selected', cb_data['index']);"
callback = CustomJS(args={'source1': source1, 'source2': source2}, code=code1+code2)

p1 = figure(tools=[], width=300, height=300, title=None, toolbar_location=None)
p2 = figure(tools=[], width=300, height=300, title=None, toolbar_location=None)
c1 = p1.circle(x='x', y='y0', source=source1)
c2 = p2.circle(x='x', y='y1', source=source2)
hover1 = HoverTool(callback=callback, renderers=[c1])
hover2 = HoverTool(callback=callback, renderers=[c2])
p1.add_tools(hover1)
p2.add_tools(hover2)

doc_layout = row([p1, p2])
curdoc().add_root(doc_layout)

2
我知道这个答案已经有一段时间了。但是对于Bokeh 2.3.0,这似乎不起作用。会出现错误Uncaught TypeError: source1.set is not a function。 在新版本中是否有可能拥有一个链接的Hover-tool? - Crysers

5

我不确定如何直接使用工具提示函数来实现此操作,但是可以使用文本图形来模拟工具提示的方式:

from bokeh.io import gridplot
from bokeh.plotting import figure, output_file, show
from bokeh.models import ColumnDataSource, Circle, HoverTool, CustomJS, Text
import numpy as np
(x, y, z) = np.arange(0, 100, 10), 100-np.arange(0, 100, 10), np.arange(0, 100, 10)/5

output_file("hover_callback.html")

p = figure(width=300, height=300, title='Hover over points', x_axis_label='x', y_axis_label='y')
p.scatter(x, y)
p2 = figure(width=300, height=300, title='Hover over points', x_axis_label='x', y_axis_label='z', x_range=p.x_range)
p2.scatter(x, z)

source = ColumnDataSource({'x': x, 'y': y, 'z': z, 'txt': ['x='+str(x[i])+', y='+str(y[i]) for i in range(len(x))], 'txt2': ['x='+str(x[i])+', z='+str(z[i]) for i in range(len(x))]})

invisible_circle = Circle(x='x', y='y', fill_color='gray', fill_alpha=0.0, line_color=None, size=20) # size determines how big the hover area will be
invisible_circle2 = Circle(x='x', y='z', fill_color='gray', fill_alpha=0.0, line_color=None, size=20)

invisible_text = Text(x='x', y='y', text='txt', text_color='black', text_alpha=0.0)
visible_text = Text(x='x', y='y', text='txt', text_color='black', text_alpha=0.5)

invisible_text2 = Text(x='x', y='z', text='txt2', text_color='black', text_alpha=0.0)
visible_text2 = Text(x='x', y='z', text='txt2', text_color='black', text_alpha=0.5)

cr = p.add_glyph(source, invisible_circle, selection_glyph=invisible_circle, nonselection_glyph=invisible_circle)
crt = p.add_glyph(source, invisible_text, selection_glyph=visible_text, nonselection_glyph=invisible_text)
cr2 = p2.add_glyph(source, invisible_circle2, selection_glyph=invisible_circle2, nonselection_glyph=invisible_circle2)
cr2t = p2.add_glyph(source, invisible_text2, selection_glyph=visible_text2, nonselection_glyph=invisible_text2)

code = "source.set('selected', cb_data['index']);"
callback = CustomJS(args={'source': source}, code=code)
p.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[cr, crt]))
p2.add_tools(HoverTool(tooltips=None, callback=callback, renderers=[cr2, cr2t]))
layout = gridplot([[p, p2]])
show(layout)

输出如下: hover example

谢谢。这跟我想到的差不多。 - Erwin Kalvelagen
1
太酷了!我想知道在bokeh的后续版本中是否会包括同步工具提示的功能--它似乎正在进行相当重要的开发。 - Peter

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接