如何用Matplotlib将两组Pandas聚合数据绘制成复合/分组柱状图?
实现分性别按年龄的柱状图可视化方案
嗨,我来帮你搞定这个Matplotlib可视化需求~首先得明确:你现在手里的两组数据是单独按性别、年龄统计的,没有把「年龄组」和「性别」的对应关系关联起来,所以第一步要先从原数据集重新整理出每个年龄组下男/女的自杀总数,这样才能绘制你想要的双柱图或独立柱状图。
第一步:重新整理数据
我们需要从suicides_russia中按「年龄+性别」双维度分组,然后转换为宽格式DataFrame(行是年龄组,列是性别,值是对应总数),这样后续绘图会非常方便:
# 双维度分组并转成宽格式 suicides_age_sex = suicides_russia.groupby(["age", "sex"])["suicides_no"].sum().unstack() # 如果你想保持之前suicides_age的排序顺序,可以手动指定年龄组的顺序 age_order = ["5-14 years", "75+ years", "15-24 years", "25-34 years", "55-74 years", "35-54 years"] suicides_age_sex = suicides_age_sex.reindex(age_order)
执行后你会得到类似这样的结构化数据:
sex female male age 5-14 years xxx xxx 75+ years xxx xxx 15-24 years xxx xxx ... ... ...
方案一:双柱图(同一年龄组的男/女柱子并排)
这种图可以直观对比每个年龄组内男女的自杀数量差异:
import matplotlib.pyplot as plt # 可选:设置一个好看的绘图风格 plt.style.use('seaborn-v0_8') # 创建双柱图 ax = suicides_age_sex.plot(kind='bar', figsize=(10, 6), width=0.7) # 配置图表标题和标签 ax.set_title('Total Suicides by Age Group & Sex', fontsize=14) ax.set_xlabel('Age Group', fontsize=12) ax.set_ylabel('Number of Suicides', fontsize=12) # 调整x轴标签的旋转角度,避免重叠 plt.xticks(rotation=45, ha='right') # 可选:给每个柱子顶部添加具体数值标签 for container in ax.containers: ax.bar_label(container, label_type='edge', fontsize=10) # 调整布局,防止标签被截断 plt.tight_layout() # 显示图表 plt.show()
方案二:两个独立的柱状图(分性别展示各年龄组数据)
如果你想把男、女的年龄组数据分开展示,可以用子图的方式:
# 创建1行2列的子图布局 fig, (ax_female, ax_male) = plt.subplots(1, 2, figsize=(14, 6)) # 第一个子图:女性各年龄组自杀数据 suicides_age_sex['female'].plot(kind='bar', ax=ax_female, color='#ff6b6b', width=0.7) ax_female.set_title('Female Suicides by Age Group', fontsize=14) ax_female.set_xlabel('Age Group', fontsize=12) ax_female.set_ylabel('Total Suicides', fontsize=12) ax_female.tick_params(axis='x', rotation=45, labelha='right') # 添加数值标签 for container in ax_female.containers: ax_female.bar_label(container, label_type='edge') # 第二个子图:男性各年龄组自杀数据 suicides_age_sex['male'].plot(kind='bar', ax=ax_male, color='#4dabf7', width=0.7) ax_male.set_title('Male Suicides by Age Group', fontsize=14) ax_male.set_xlabel('Age Group', fontsize=12) ax_male.set_ylabel('Total Suicides', fontsize=12) ax_male.tick_params(axis='x', rotation=45, labelha='right') # 添加数值标签 for container in ax_male.containers: ax_male.bar_label(container, label_type='edge') # 调整整体布局,避免元素重叠 plt.tight_layout() plt.show()
这样就能完美实现你想要的两种可视化效果啦~
内容的提问来源于stack exchange,提问作者A A
相关产品推荐
相关产品推荐

