如何用Bokeh绘制DataFrame中Year与A/B/C/D列的柱状图?
代码补充方案
根据需求(每个年份对应一组A、B、C、D类别的柱状图),补充后的完整代码如下:
import pandas as pd from bokeh.io import output_file, show from bokeh.plotting import figure from bokeh.palettes import Spectral6 from bokeh.models import ColumnDataSource, FactorRange from bokeh.transform import factor_cmap # 将原始宽格式DataFrame转为长格式,适配Bokeh分组绘图需求 df_melted = df.melt(id_vars='Year', var_name='类别', value_name='计数') # 构造年份与类别的组合因子,用于分组柱状图的x轴 年份列表 = [str(y) for y in df['Year'].unique()] 类别列表 = ['A', 'B', 'C', 'D'] x轴因子 = [(year, cat) for year in 年份列表 for cat in 类别列表] # 给数据源添加组合字段,绑定年份和类别 df_melted['年份_类别'] = list(zip(df_melted['Year'].astype(str), df_melted['类别'])) output_file("bar_charts.html") source = ColumnDataSource(df_melted) # 补充figure的x_range参数,使用分组因子范围 p = figure(x_range=FactorRange(*x轴因子), height=350, title="各年份类别计数") # 补充vbar的核心参数,同时用颜色区分不同类别 p.vbar(x='年份_类别', top='计数', width=0.9, source=source, fill_color=factor_cmap('年份_类别', palette=Spectral6[:4], factors=类别列表, start=1, end=2), legend_field='类别') # 优化图表可读性 p.xaxis.major_label_orientation = 1.2 # 旋转x轴标签避免重叠 p.legend.title = "类别" show(p)
关键参数说明:
figure的x_range:通过FactorRange(*x轴因子)定义分组式x轴,确保每个年份下能展示A、B、C、D四个类别的柱子。vbar的x:传入组合后的年份_类别字段实现分组定位,top传入数值列计数作为柱子高度,同时指定source完成数据绑定。
如果你的需求是每个年份单独生成一张独立柱状图(每行对应一个独立图表),可以改用网格布局实现:
import pandas as pd from bokeh.io import output_file, show from bokeh.plotting import figure from bokeh.palettes import Spectral6 from bokeh.models import ColumnDataSource from bokeh.layouts import gridplot output_file("bar_charts.html") plots = [] # 遍历DataFrame每行,生成对应年份的独立柱状图 for _, row in df.iterrows(): 年份 = row['Year'] # 构造单年份的数据源 data = {'类别': ['A', 'B', 'C', 'D'], '计数': [row['A'], row['B'], row['C'], row['D']]} source = ColumnDataSource(data) # 创建单图并配置参数 p = figure(x_range=['A', 'B', 'C', 'D'], height=250, title=f"年份{年份}计数") p.vbar(x='类别', top='计数', width=0.9, source=source, fill_color=Spectral6[:4]) plots.append(p) # 以2列布局展示所有图表 grid = gridplot(plots, ncols=2) show(grid)
内容的提问来源于stack exchange,提问作者Tranquil Oshan
相关产品推荐
相关产品推荐

