You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Bokeh中为分类轴柱状图添加Range Tool?

解决Bokeh分类轴柱状图添加RangeTool的问题

报错的核心原因是RangeTool仅支持数值型的Range1d轴,不支持分类型的FactorRange轴,直接用分类值作为x轴时,Bokeh会自动创建FactorRange,导致和RangeTool不兼容。

解决方案思路

将分类数据映射为数值索引,用数值轴模拟分类轴,同时手动设置x轴刻度标签为原分类名称,既满足RangeTool的要求,又能保持分类显示的效果。

修正后的完整代码

from bokeh.io import output_file, show
from bokeh.models import ColumnDataSource, RangeTool
from bokeh.plotting import figure
from bokeh.layouts import gridplot

# 示例数据
AccountID = ['A1233', 'B3453', 'C1213', 'D1241', 'E5678', 'F9012', 'G3456', 'H7890']
Value = [10, 20, 30, 40, 25, 35, 15, 45]

# 为分类分配数值索引,用于数值轴
x_indices = list(range(len(AccountID)))
source = ColumnDataSource(data=dict(x=x_indices, y=Value, account=AccountID))

# 主图:使用数值x轴,手动设置刻度标签为分类名称
p = figure(
    x_range=(0, len(AccountID)-1), 
    height=400, 
    title="带Range Tool的分类柱状图",
    x_axis_label="Account ID"
)
p.vbar(x='x', top='y', width=0.9, source=source)
# 设置x轴刻度和标签,替换数值为分类名称
p.xaxis.ticker = x_indices
p.xaxis.major_label_overrides = dict(zip(x_indices, AccountID))

# RangeTool用的小图,同样使用数值轴
range_plot = figure(
    height=130, 
    x_range=p.x_range, 
    y_range=p.y_range,
    toolbar_location=None,
    x_axis_label="Account ID"
)
range_plot.vbar(x='x', top='y', width=0.9, source=source)
range_plot.xaxis.ticker = x_indices
range_plot.xaxis.major_label_overrides = dict(zip(x_indices, AccountID))

# 初始化并添加RangeTool
range_tool = RangeTool(x_range=p.x_range)
range_plot.add_tools(range_tool)
range_plot.toolbar.active_multi = range_tool

# 垂直组合主图和工具图
layout = gridplot([[p], [range_plot]])

output_file("bar_chart_with_range_tool.html")
show(layout)

关键说明

  • 用x_indices将分类转换为0、1、2...的数值索引,作为x轴的实际计算值
  • 通过xaxis.ticker和xaxis.major_label_overrides将数值刻度替换为原分类名称,实现分类轴的视觉效果
  • 修复了原代码中变量名错误(如Account应为AccountID,y应为Value)
  • 使用gridplot将主图和RangeTool小图垂直排列,保证交互联动

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.29 07:12:38