基于数据为Bokeh条形图设置差异化颜色
为Bokeh条形图根据数据对比结果设置不同颜色
你的原代码存在逻辑问题:两层嵌套循环会遍历所有avg_list和min_list的组合,最终color变量只会保留最后一次循环的结果,导致所有条形图都使用同一个颜色,无法实现按索引逐一对比并单独设置颜色的需求。
修正方案
- 按索引同时遍历两个列表,生成每个条形对应的颜色列表
- 将颜色列表加入到
ColumnDataSource中 - 在
vbar中直接引用数据源的颜色字段设置填充色
完整代码示例
from bokeh.plotting import figure, show from bokeh.models import ColumnDataSource from bokeh.transform import dodge # 假设你的基础数据 x_values = ['类别1', '类别2', '类别3', '类别4'] avg_list = [120, 90, 150, 80] min_list = [100, 85, 130, 75] # 生成对应每个条形的颜色列表 color_list = [] for avg, min_val in zip(avg_list, min_list): avg_float = float(avg) min_float = float(min_val) # 判断avg是否比min高出10%:avg >= min * 1.1 if avg_float >= min_float * 1.1: color_list.append('red') else: color_list.append('lightskyblue') # 创建数据源,加入颜色字段 cds = ColumnDataSource(data={ 'x': x_values, 'AVG': avg_list, 'MIN': min_list, 'color': color_list }) p = figure(x_range=x_values, title='AVG与MIN对比') # 绘制AVG条形图,使用数据源中的color字段设置填充色 p.vbar( x=dodge('x', 0.2, range=p.x_range), top='AVG', width=0.38, fill_color='color', source=cds, legend_label="AVG", ) # 可选:绘制MIN条形图作为对比 p.vbar( x=dodge('x', -0.2, range=p.x_range), top='MIN', width=0.38, fill_color='lightgray', source=cds, legend_label="MIN", ) p.legend.location = "top_left" show(p)
关键说明
- 使用
zip(avg_list, min_list)可以按索引同时遍历两个列表的对应元素,确保每一组数据都是同索引的对比 - 将颜色列表存入
ColumnDataSource后,vbar的fill_color直接指定为字段名'color',Bokeh会自动为每个条形匹配对应的颜色
内容的提问来源于stack exchange,提问作者ptr808
相关产品推荐
相关产品推荐

