如何在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
相关产品推荐
相关产品推荐

