如何为列数及列名未知的DataFrame绘制Seaborn堆叠柱状图
动态绘制Seaborn堆叠柱状图(适配未知列数的透视表)
实现思路
- 自动提取透视表中所有需要堆叠的数值列名,无需提前获知列的数量和具体名称
- 维护一个
bottom累加数组,每绘制完一层柱状图,就将该层的数值累加到bottom中,作为下一层柱状图的底部基线 - 配合Seaborn内置调色板自动为不同堆叠层分配差异化颜色,无需手动逐个指定
完整实现代码
场景1:透视表索引为X轴字段(如示例中的month字段)
import seaborn as sns import pandas as pd import numpy as np import matplotlib.pyplot as plt # 替换为你自己的透视表变量 pivot_df = your_pivot_table # 自动获取X轴字段名(即透视表索引名) x_col = pivot_df.index.name # 自动获取所有需要堆叠的数值列名 value_cols = pivot_df.columns.tolist() # 初始化底部基线数组,长度和X轴类别数一致,初始值为0 bottom = np.zeros(len(pivot_df)) # 自动生成和数值列数量匹配的配色 palette = sns.color_palette("husl", n_colors=len(value_cols)) plt.figure(figsize=(10, 6)) for idx, col in enumerate(value_cols): # 绘制当前层柱状图,指定底部基线为之前所有层的累加值 sns.barplot(x=pivot_df.index, y=pivot_df[col], bottom=bottom, color=palette[idx], label=col) # 累加当前层数值到基线,供下一层使用 bottom += pivot_df[col].values # 图表细节优化 plt.xlabel(x_col) plt.ylabel("数值") plt.legend(title="堆叠类别") plt.show()
场景2:透视表已重置索引,X轴为普通列
import seaborn as sns import pandas as pd import numpy as np import matplotlib.pyplot as plt # 替换为你自己的透视表变量 pivot_df = your_pivot_table # 替换为你实际的X轴列名,也可以动态指定第一列为X轴 x_col = "month" # 过滤掉X轴列,剩余列自动判定为需要堆叠的数值列 value_cols = [col for col in pivot_df.columns if col != x_col] bottom = np.zeros(len(pivot_df)) palette = sns.color_palette("husl", n_colors=len(value_cols)) plt.figure(figsize=(10, 6)) for idx, col in enumerate(value_cols): sns.barplot(x=x_col, y=col, data=pivot_df, bottom=bottom, color=palette[idx], label=col) bottom += pivot_df[col].values plt.xlabel(x_col) plt.ylabel("数值") plt.legend(title="堆叠类别") plt.show()
注意事项
- 如果透视表存在空值,建议先执行
pivot_df = pivot_df.fillna(0)将空值替换为0,避免绘制报错 - 可以将调色板参数
"husl"替换为"Set2"、"rainbow"等Seaborn支持的其他调色板名称调整配色 - 如需调整柱子宽度,可以在
sns.barplot中添加width参数指定,比如width=0.8
内容的提问来源于stack exchange,提问作者mrgou
相关产品推荐
相关产品推荐

