如何用Pandas为分组DataFrame的每个月份生成独立饼图?
解决Pandas绘制月度独立支出饼图的问题
问题根源
你当前的monthly_expenditure是**多层索引(日期+地点)**的DataFrame,直接调用plot.pie()会把所有月份的支出数据合并计算比例,导致所有数据挤在一个饼图里。需要先将数据重塑为「每个月对应一行/列,各地点支出为字段」的结构,再逐个月份生成饼图。
解决方案步骤
1. 重塑数据结构
先把多层索引的DataFrame转换为以月份为索引、地点为列的格式,用unstack()实现:
# 假设支出数值列名为'amount',先选中该列再拆分索引 monthly_expenditure_unstacked = monthly_expenditure['amount'].unstack(level='location') # 如果你的sum结果只有数值列,也可以直接用: # monthly_expenditure_unstacked = monthly_expenditure.unstack(level='location')
2. 生成独立月度饼图
方式1:逐个生成单独饼图
遍历每个月份,单独绘制饼图:
import matplotlib.pyplot as plt for date, monthly_data in monthly_expenditure_unstacked.iterrows(): # 过滤掉无支出的地点(可选,避免空切片) valid_data = monthly_data.dropna() # 绘制饼图 plt.figure(figsize=(6, 6)) valid_data.plot.pie( autopct='%1.1f%%', # 显示百分比 title=f'月度支出分布 - {date.strftime("%Y-%m")}' ) plt.ylabel('') # 移除默认y轴标签,优化美观度 plt.show()
方式2:多饼图同画布展示
如果想把所有月度饼图放在一个画布上,用子图布局:
import matplotlib.pyplot as plt num_months = len(monthly_expenditure_unstacked) cols = 2 # 每行展示2个饼图 rows = (num_months + cols - 1) // cols # 计算所需行数 # 创建画布和子图 fig, axes = plt.subplots(rows, cols, figsize=(12, 6*rows)) axes = axes.flatten() # 转为一维数组方便遍历 # 逐个绘制饼图 for idx, (date, monthly_data) in enumerate(monthly_expenditure_unstacked.iterrows()): valid_data = monthly_data.dropna() valid_data.plot.pie( autopct='%1.1f%%', title=f'{date.strftime("%Y-%m")}', ax=axes[idx] ) axes[idx].set_ylabel('') # 隐藏多余的空白子图 for j in range(idx+1, len(axes)): axes[j].axis('off') plt.tight_layout() plt.show()
关键说明
- 必须确保每个饼图只包含单个月份的各地点支出数据,避免跨月份数据混合。
- 如果存在支出为0或NaN的地点,建议用
dropna()或monthly_data[monthly_data > 0]过滤,避免饼图出现空切片。
内容的提问来源于stack exchange,提问作者dmr
相关产品推荐
相关产品推荐

