如何使用Seaborn高效绘制基于Pandas支出数据的堆叠条形图
更简洁的Seaborn堆叠条形图实现方案
当然有更优的实现方式!既可以简化你原来的Pandas流程,又能用上Seaborn的美观样式,甚至可以纯Seaborn API实现堆叠效果,下面给你两种实用方案:
方案一:简化Pandas堆叠条形图 + Seaborn样式(最便捷)
你原来的思路没问题,但可以把聚合和绘图步骤压缩得更简洁,同时用Seaborn的全局样式美化图表,兼顾效率和美观:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 你的原始数据 d = {'Month': ['Jan', 'Jan', 'Jan', 'Feb', 'Feb', 'Mar', 'Mar', 'Mar', 'Mar'], 'Amount': [5, 65, 29, 200, 28.5, 12, 4, 100, 21], 'Category': ['Travel', 'Food', 'Dentist', 'Dentist', 'Food', 'Travel', 'Food', 'Sport', 'Sport']} df = pd.DataFrame(d) # 启用Seaborn的美观样式 sns.set_style("whitegrid") # 一步完成聚合+堆叠条形图绘制 df.groupby(['Month', 'Category'])['Amount'].sum().unstack().plot.bar( stacked=True, cmap='tab20', figsize=(8,6) ) # 图表美化 plt.ylabel('Total Expense') plt.title('Monthly Expenses Breakdown by Category') plt.legend(title='Expense Category', bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
关键简化点:
- 用
groupby(...).sum().unstack()替代你原来的groupby -> reset_index -> pivot,一行完成数据格式转换 - 启用Seaborn样式后,Pandas绘制的图表会自动套用Seaborn的配色和风格,无需额外修改
方案二:纯Seaborn实现堆叠条形图(高度自定义)
如果你想完全基于Seaborn的API实现(而非依赖Pandas的plot方法),可以通过计算累计值来实现堆叠效果,方便你对图表细节做更精细的调整:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 原始数据 d = {'Month': ['Jan', 'Jan', 'Jan', 'Feb', 'Feb', 'Mar', 'Mar', 'Mar', 'Mar'], 'Amount': [5, 65, 29, 200, 28.5, 12, 4, 100, 21], 'Category': ['Travel', 'Food', 'Dentist', 'Dentist', 'Food', 'Travel', 'Food', 'Sport', 'Sport']} df = pd.DataFrame(d) # 1. 聚合每个月每个类别的总支出 agg_df = df.groupby(['Month', 'Category'], as_index=False)['Amount'].sum() # 2. 计算每个类别在当月的堆叠起点(前面所有类别的金额总和) agg_df['cumulative_amount'] = agg_df.groupby('Month')['Amount'].cumsum() - agg_df['Amount'] # 设置Seaborn样式 sns.set_style("whitegrid") plt.figure(figsize=(8,6)) # 3. 循环绘制每个类别的堆叠条形 for category in agg_df['Category'].unique(): subset = agg_df[agg_df['Category'] == category] sns.barplot( x='Month', y='Amount', data=subset, bottom=subset['cumulative_amount'], label=category ) # 图表美化 plt.ylabel('Total Expense') plt.title('Monthly Expenses Breakdown by Category') plt.legend(title='Expense Category', bbox_to_anchor=(1.05, 1), loc='upper left') plt.tight_layout() plt.show()
核心逻辑:
cumulative_amount字段代表当前类别在当月堆叠条形中的底部位置,即该类别之前所有类别的金额总和- 通过给每个类别的
barplot设置bottom参数,实现条形堆叠的效果,完全基于Seaborn API,风格统一
方案选择建议:
- 如果追求快速出图,优先选方案一,代码最简洁,兼顾Pandas的便捷和Seaborn的美观
- 如果需要对图表元素(如颜色、标签、条形样式)做高度自定义,选方案二,纯Seaborn实现更灵活
内容的提问来源于stack exchange,提问作者Fasteno
相关产品推荐
相关产品推荐

