You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

Bokeh交互式图例隐藏Glyph后Hover工具失效,寻求解决方案

解决Bokeh交互式图例隐藏Glyph后Hover工具失效的问题

我太懂你遇到的这个糟心问题了——当用交互式图例隐藏中间的某条线后,排在它下面的线条就完全无法被Hover工具识别了,可上面的线条却一点事儿没有。这确实和Bokeh早期处理隐藏Glyph时的逻辑缺陷有关,之前就有过Hover工具误读已隐藏元素的Bug,现在这个问题本质上是渲染器的状态跟踪或索引匹配出了问题。

可行的解决办法

方法1:为每个渲染器单独配置Hover工具(最推荐)

这个思路很直接:让每条线对应专属的Hover工具,彻底避免共享工具时的索引混乱。修改后的代码如下:

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

x = np.arange(0, 10, 1)
x2 = x/2
x3 = x/4

p = figure()

# 先为每条线创建独立的渲染器对象
r1 = p.line(x, x, legend_label="Line 1")
r2 = p.line(x, x2, legend_label="Line 2")
r3 = p.line(x, x3, legend_label="Line 3")

# 给每个渲染器绑定专属的Hover工具
hover1 = HoverTool(renderers=[r1], tooltips=[("x", "@x"), ("y", "@y")])
hover2 = HoverTool(renderers=[r2], tooltips=[("x", "@x"), ("y", "@y")])
hover3 = HoverTool(renderers=[r3], tooltips=[("x", "@x"), ("y", "@y")])

# 将所有Hover工具添加到图表中
p.add_tools(hover1, hover2, hover3)
p.legend.click_policy = "hide"

show(p)

这样配置后,每条线的Hover工具只盯着自己对应的渲染器,不管其他线条是否被隐藏,Hover提示都能正常触发。

方法2:用JS回调动态更新Hover的作用对象

如果你不想创建多个Hover工具,可以通过JavaScript回调监听图例的点击事件,动态筛选出当前可见的渲染器,更新Hover工具的作用列表:

import numpy as np
from bokeh.plotting import figure, show
from bokeh.models import HoverTool, CustomJS

x = np.arange(0, 10, 1)
x2 = x/2
x3 = x/4

p = figure()

r1 = p.line(x, x, legend_label="Line 1")
r2 = p.line(x, x2, legend_label="Line 2")
r3 = p.line(x, x3, legend_label="Line 3")

# 初始化Hover工具,默认作用于所有渲染器
hover = HoverTool(tooltips=[("x", "@x"), ("y", "@y")], renderers=[r1, r2, r3])
p.add_tools(hover)
p.legend.click_policy = "hide"

# 编写JS回调,每次点击图例后更新Hover的渲染器列表
callback = CustomJS(args=dict(renderers=[r1, r2, r3], hover=hover), code="""
    // 过滤出当前可见的渲染器
    hover.renderers = renderers.filter(r => r.visible);
""")

# 给图例绑定点击事件回调
p.legend.js_on_click(callback)

show(p)

这个回调会在每次点击图例项时,自动把Hover工具的作用对象更新为当前显示的线条,完美解决隐藏后的失效问题。

方法3:升级到最新版Bokeh

其实这个问题在Bokeh的后续稳定版本(比如2.4.0及以后)中已经被官方修复了。如果你还在使用旧版本,直接升级到最新版可能是最省心的方案:

pip install --upgrade bokeh

问题复现的现象

  • 无隐藏Glyph时:三条线都能正常触发Hover工具,显示对应的x、y坐标信息。
  • 隐藏Line 2后:鼠标移到Line 3上时,Hover工具没有任何反应,但Line 1的Hover功能依然正常工作。

内容的提问来源于stack exchange,提问作者BikeControl

火山引擎 最新活动