Bokeh堆叠嵌套分类柱状图:多分类场景下索引错误排查
解决Bokeh堆叠嵌套分类柱状图的IndexError问题
需要实现堆叠嵌套分类柱状图,现有4个场景(Scenario1-Scenario4),希望配置更多分类(Cat),但目前仅当分类数量与场景数量相等时代码能正常运行,添加更多分类会触发IndexError: list index out of range,推测问题出在生成factors的代码行。
错误原因
原来的factors生成逻辑存在问题:使用enumerate(subsystems)获取索引ind,再通过systems[ind]关联场景,但当分类数量超过场景数量时,ind会超出systems的索引范围(比如6个分类对应索引0-5,而场景只有4个,索引仅到3),直接导致索引越界。
正确逻辑应为每个场景对应所有分类:遍历每个场景,再遍历每个分类生成嵌套因子。同时,所有状态数据(count_closed/count_open/count_waived)的长度必须与factors的长度一致(场景数×分类数),否则会因数据不匹配报错。
修正后的代码
from bokeh.models import ColumnDataSource, FactorRange from bokeh.plotting import figure, show # 场景列表(固定4个) systems = ["Scenario1", "Scenario2", "Scenario3", "Scenario4"] # 分类列表(扩展为6个,可按需添加更多) subsystems = ["Cat1","Cat2", "Cat3", "Cat4", "Cat5", "Cat6"] # 正确生成嵌套因子:每个场景对应所有分类 factors = [(system, subsystem) for system in systems for subsystem in subsystems] # 状态数据:每个场景下6个分类的对应数值,总长度为4*6=24 count_closed = [52,52,49,26,9,8, 32,20,33,66,9,8, 15,18,22,25,7,10, 30,28,19,21,5,6] count_open = [0,0,1,0,2,3, 1,0,0,2,1,0, 0,1,0,0,2,1, 1,0,2,0,1,0] count_waived = [3,1,0,0,2,1, 0,3,1,0,0,2, 1,0,3,1,0,0, 0,2,1,0,3,1] statuses = ["count_closed", "count_open", "count_waived"] data = dict(factors=factors, count_closed=count_closed, count_open=count_open, count_waived=count_waived ) source = ColumnDataSource(data=data) p = figure(x_range=FactorRange(*factors), plot_height=350, title="每个场景对应多个分类的堆叠柱状图", toolbar_location='right', tools="hover", tooltips="$name: @$name") p.vbar_stack(statuses, x="factors", width=0.9, alpha=0.5, color=["navy","red","pink"], source=source, legend_label=statuses) p.y_range.start = 0 p.x_range.range_padding = 0.1 p.xaxis.major_label_orientation = 1.2 p.xgrid.grid_line_color = None p.legend.location = "top_center" p.legend.orientation = "horizontal" show(p)
关键修正点
- 调整
factors生成逻辑:先遍历场景再遍历分类,确保每个场景能对应所有分类,彻底解决索引越界问题 - 同步更新所有状态数据的长度:保证每个场景下的每个分类都有对应的三个状态数值,总长度等于场景数×分类数
- 微调图表高度和x轴标签倾斜角度,提升大分类数量下的可读性
内容的提问来源于stack exchange,提问作者Brain_overflowed
相关产品推荐
相关产品推荐

