如何按年份分多子图行绘制长格式数据集的柱状图
实现方案
首先导入必要依赖:
import pandas as pd import matplotlib.pyplot as plt # 第二种方案需要额外导入seaborn import seaborn as sns
方法1:Matplotlib+Pandas原生绘图(无额外依赖)
不需要安装其他库,手动拆分数据绘制子图,灵活度高:
# 你的原始数据集 data = {'Year':[2019,2019,2019,2020,2020,2020,2021,2021,2021], 'Month_diff':[0,1,2,0,1,2,0,1,2], 'data': [12,10,13,16,12,18,19,45,34]} df = pd.DataFrame(data) # 获取所有年份,创建3行1列的子图画布 year_list = df['Year'].unique() fig, axes = plt.subplots(nrows=3, ncols=1, figsize=(6, 9)) # 循环遍历每个年份,在对应子图绘制柱状图 for index, year in enumerate(year_list): current_df = df[df['Year'] == year] current_df.plot(x='Month_diff', y='data', kind='bar', ax=axes[index], title=f'{year}年数据') # 可选:调整x轴标签不旋转,更易读 axes[index].tick_params(axis='x', rotation=0) axes[index].set_ylabel('数值') # 自动调整子图间距避免重叠 plt.tight_layout() plt.show()
方法2:Seaborn FacetGrid 快速实现
代码更简洁,自动适配子图布局:
sns.set_theme() # 按Year字段生成行子图,可调整height和aspect修改子图尺寸 g = sns.FacetGrid(df, row='Year', height=3, aspect=2) # 映射柱状图到子图,指定x、y字段和x轴排序 g.map(sns.barplot, 'Month_diff', 'data', order=[0,1,2], color='#1f77b4') # 可选:自定义坐标轴和标题样式 g.set_axis_labels('Month_diff', 'data') g.set_titles(row_template='{row_name}年') plt.show()
如果你更习惯你提到的多列绘图方式,可以先把长格式数据转为宽格式再绘图:
df_wide = df.pivot(index='Month_diff', columns='Year', values='data') # 转宽后每列对应一个年份,就可以用你熟悉的df.plot语法分别绘制子图
内容的提问来源于stack exchange,提问作者Patthebug
相关产品推荐
相关产品推荐

