pandas如何基于groupby绘制按月份分组的企业利润分组柱状图
pandas结合groupby绘制指定维度分组柱状图实现方法
你可以按照「聚合预处理-绘图」的两步流程实现,groupby的核心作用是提前汇总同维度下的利润值,避免原始12条样本存在同公司同月份多条记录时绘图值计算错误,具体实现如下:
前置准备:导入依赖与基础数据处理
首先导入需要的库,提前处理月份字段的排序避免绘图顺序错乱:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 加载数据集,以下为匹配你描述的12条样本模拟数据,替换成自己的文件读入代码即可 data = [ *[('dec', 'a', 120), ('dec', 'b', 150), ('dec', 'c', 90)]*2, *[('jan', 'a', 180), ('jan', 'b', 160), ('jan', 'c', 210)], *[('feb', 'a', 200), ('feb', 'b', 190), ('feb', 'c', 170)] ] df = pd.DataFrame(data, columns=['month', 'companyname', 'profit']) # 固定月份排序,避免按字母排序导致dec/feb/jan顺序混乱 df['month'] = pd.Categorical(df['month'], categories=['dec', 'jan', 'feb'], ordered=True)
核心步骤:用groupby做维度聚合
按x轴、分组颜色对应的两个维度(公司名、月份)分组,对利润字段做聚合:如果你的数据没有重复记录,聚合后结果和原表一致不会改变数值;如果有重复记录,会自动汇总得到正确的绘图值。
# as_index=False保持扁平表结构,直接适配后续绘图接口 df_agg = df.groupby(['companyname', 'month'], as_index=False)['profit'].sum()
绘图实现(两种方案二选一即可)
- 方案1:seaborn实现(排版默认适配分组逻辑,效果更贴合示例图)
plt.figure(figsize=(8, 5)) sns.barplot( data=df_agg, x='companyname', y='profit', hue='month', # 按月份映射分组柱子颜色,自动生成对应图例 palette='Set2' ) plt.title('Corporate profit by month') plt.xlabel('Company Name') plt.ylabel('Profit') plt.tight_layout() plt.show()
- 方案2:pandas原生接口实现(无需额外安装seaborn)
对聚合后的结果做unstack转换为宽表,直接调用pandas的柱状图接口:
# 转换为公司为行、月份为列的宽表结构 df_wide = df_agg.groupby(['companyname', 'month'])['profit'].sum().unstack() df_wide.plot(kind='bar', figsize=(8,5), color=['#66c2a5','#fc8d62','#8da0cb']) plt.title('Corporate profit by month') plt.xlabel('Company Name') plt.ylabel('Profit') plt.xticks(rotation=0) plt.tight_layout() plt.show()
提示:如果需要统计同组利润的平均值、中位数而非求和,把groupby后的
.sum()替换成.mean()/.median()即可。
内容的提问来源于stack exchange,提问作者Jack
相关产品推荐
相关产品推荐

