如何绘制带双Y轴的分组并列柱状图(dodged barplot)
双Y轴并列柱状图实现方案
需求说明
- 每个区域旁并列展示收入与人口的柱状图
- 针对人口(万级)和收入(十位数)的量级差异,使用双Y轴适配
- 在每个柱状图顶部标注对应数值
实现代码
import matplotlib.pyplot as plt import seaborn as sns import pandas as pd # 准备数据 data = pd.DataFrame({'region': ['A', 'B', 'C'], 'population': [1000, 2000, 30000], 'income': [40, 50, 60]}) # 设置柱状图宽度,确保并列显示 bar_width = 0.35 x = range(len(data['region'])) # 创建画布和主坐标轴(对应收入) fig, ax1 = plt.subplots(figsize=(8, 5)) # 绘制收入柱状图(主Y轴) bars1 = ax1.bar([i - bar_width/2 for i in x], data['income'], width=bar_width, label='收入', color='#1f77b4') # 给收入柱子添加顶部数值标签 for bar in bars1: height = bar.get_height() ax1.text(bar.get_x() + bar.get_width()/2., height, f'{height}', ha='center', va='bottom') # 配置主Y轴属性 ax1.set_xlabel('区域') ax1.set_ylabel('收入') ax1.set_xticks(x) ax1.set_xticklabels(data['region']) ax1.legend(loc='upper left') # 创建次坐标轴(对应人口) ax2 = ax1.twinx() # 绘制人口柱状图(次Y轴) bars2 = ax2.bar([i + bar_width/2 for i in x], data['population'], width=bar_width, label='人口', color='#ff7f0e') # 给人口柱子添加顶部数值标签 for bar in bars2: height = bar.get_height() ax2.text(bar.get_x() + bar.get_width()/2., height, f'{height}', ha='center', va='bottom') # 配置次Y轴属性 ax2.set_ylabel('人口') ax2.legend(loc='upper right') # 调整布局避免标签重叠 plt.tight_layout() plt.show()
代码说明
- 并列柱状图实现:通过调整两组柱子的x轴偏移量(
i - bar_width/2和i + bar_width/2),实现同一区域下收入与人口柱子的并排展示 - 双Y轴适配:利用
twinx()创建次坐标轴,分别承载量级差异极大的收入(左轴)和人口(右轴)数据,避免单轴下的展示失真 - 顶部数值标注:遍历每个柱状图对象,调用
text()方法在柱子顶部添加对应数值,让数据展示更直观
内容的提问来源于stack exchange,提问作者zesla
相关产品推荐
相关产品推荐

