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

如何在Python Bokeh中添加带专属图标的Hide操作工具切换图例显示?

实现Bokeh自定义图例显示/隐藏工具的最优方案

嘿,这个需求我帮不少人解决过,最优实现方式其实很清晰,咱们一步步来,保证你能快速上手:

1. 先准备好你的专属图标

如果是SVG格式的图标最方便,直接把SVG代码存成字符串就行;要是是PNG/JPG,转成Base64编码也能用。我给你放个示例的眼睛图标(用来表示显示/隐藏),你直接替换成自己的专属图标就行:

# 示例SVG图标,替换成你自己的专属图标代码即可
ICON_SVG = """
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
  <path d="M10 12a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
  <path fill-rule="evenodd" d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm1-11a1 1 0 1 0-2 0v2a1 1 0 1 0 2 0V7z" clip-rule="evenodd"/>
</svg>

2. 用Bokeh内置的CustomAction创建工具

Bokeh专门提供了CustomAction类来添加自定义操作工具,不用自己写复杂的Tool子类,这是最简洁的方式。我们只需要给它绑定一个JS回调,用来切换图例的可见性。

这里推荐用Bokeh的模型API来操作图例,而不是直接改DOM,这样能保证图表的状态一致性:

function toggleLegend() {
  // 通过name属性找到我们的图例模型
  const legend = Bokeh.documents[0].get_model_by_name('my_legend');
  if (legend) {
    // 切换可见性状态
    legend.visible = !legend.visible;
    // 通知Bokeh文档更新界面
    Bokeh.documents[0].change.emit();
  }
}

3. 整合到你的图表中

接下来把这些部件拼起来,注意给图例设置一个唯一的name属性,这样JS才能精准找到它:

完整可运行示例代码

from bokeh.plotting import figure, show
from bokeh.models import CustomAction, Legend

# 1. 自定义图标(替换成你的专属图标)
ICON_SVG = """
<svg width="20" height="20" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg">
  <path d="M10 12a2 2 0 1 0 0-4 2 2 0 0 0 0 4z"/>
  <path fill-rule="evenodd" d="M10 18a8 8 0 1 0 0-16 8 8 0 0 0 0 16zm1-11a1 1 0 1 0-2 0v2a1 1 0 1 0 2 0V7z" clip-rule="evenodd"/>
</svg>
"""

# 2. 创建基础图表和数据
p = figure(width=600, height=400, tools="pan,zoom_reset,save")
line1 = p.line([1,2,3,4], [1,4,2,3], color="red", line_width=2)
line2 = p.line([1,2,3,4], [2,1,4,3], color="blue", line_width=2)

# 3. 创建图例并设置唯一name,方便JS定位
legend = Legend(
    items=[("红色线条", [line1]), ("蓝色线条", [line2])],
    name="my_legend"  # 这个name要和JS里的对应上
)
p.add_layout(legend)

# 4. 定义切换图例的JS回调
toggle_legend_js = """
function toggleLegend() {
  const legend = Bokeh.documents[0].get_model_by_name('my_legend');
  if (legend) {
    legend.visible = !legend.visible;
    Bokeh.documents[0].change.emit();
  }
}
"""

# 5. 创建自定义工具
hide_legend_tool = CustomAction(
    icon=ICON_SVG,
    callback=toggle_legend_js,
    title="切换图例显示/隐藏"  # 鼠标悬停时的提示文字
)

# 6. 添加工具到图表工具栏
p.add_tools(hide_legend_tool)

# 显示图表
show(p)

为什么这是最优方案?

  • 轻量简洁:用Bokeh内置的CustomAction,不需要自定义复杂的Tool类,代码量少易维护
  • 状态一致:通过Bokeh模型API操作图例可见性,而不是直接修改DOM,确保图表状态和UI同步
  • 高度定制:专属图标可以轻松替换,只需要修改ICON_SVG或者换成Base64编码的图片
  • UI统一:自定义工具会自动融入Bokeh的工具栏,和内置工具风格保持一致

额外小提示

  • 如果是在Bokeh Server环境下,也可以用Python回调,但JS回调更适合纯前端的交互场景,响应更快
  • 要是有多个图例,只需要调整JS里的逻辑,比如通过类名bk-legend批量切换,或者给每个图例设置不同的name单独控制
  • 图标建议用20x20像素的尺寸,和Bokeh内置工具图标大小一致,保证UI美观

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

火山引擎 最新活动