如何使用twinx()绘制X轴为公司名称的双Y轴柱状图?
双Y轴绘图异常排查与修正
核心问题定位
- 列映射完全错配:按你提供的数据集列顺序,
columns[1]对应percentage(占比类次Y轴指标)、columns[2]对应status_mission_2_y(失败任务数类主Y轴指标),原代码靠硬索引取列时,把两个Y轴的展示指标完全搞反,不符合需求。 - 图层完全遮挡:双Y轴下两个图层都绘制同宽度、同X坐标位置的柱状图,后绘制的次Y轴柱状图会完全盖住主Y轴的内容,根本无法同时展示两组数据。
- 视觉混淆:Seaborn默认柱状图自带半透明填充和误差棒,叠加后会出现颜色混叠、边界模糊的问题,进一步降低可读性。
修正实现方案
- 放弃硬索引取列的逻辑,通过列名显式绑定X轴、主Y轴、次Y轴的对应数据,避免数据集列顺序变动导致错配。
- 调整图层视觉差异:主Y轴用实心柱状图展示任务失败总量,次Y轴用带标记的折线图展示失败占比,从根源上避免同位置图层遮挡。
- 关闭柱状图默认误差棒,调整X轴标签角度避免文字重叠,开启自动布局防止标签被画布裁剪。
可直接运行的修正代码
import matplotlib.pyplot as plt import seaborn as sns def twinplot(data): # 显式绑定对应列,匹配绘图需求 x_col = "company_name" y_main = "status_mission_2_y" # 主Y轴:任务失败数量 y_sub = "percentage" # 次Y轴:任务失败占比 plt.figure(figsize=(15, 8)) # 绘制主Y轴柱状图 ax = sns.barplot( x=x_col, y=y_main, data=data, color="#4c72b0", errorbar=None # 关闭默认误差线 ) ax.set_ylabel("任务失败数量", fontsize=12) ax.set_xlabel("企业名称", fontsize=12) # 生成联动的次Y轴 ax2 = ax.twinx() # 绘制次Y轴占比折线 sns.lineplot( x=x_col, y=y_sub, data=data, ax=ax2, color="#dd8452", marker="o", linewidth=2 ) ax2.set_ylabel("任务失败占比", fontsize=12) # 调整显示细节 plt.xticks(rotation=45, ha="right") plt.tight_layout() plt.show() # 调用方式 # twinplot(ten_company_missions_failed)
双柱状图场景适配
如果确实需要次Y轴也使用柱状图展示占比,需要手动对同X类别下的两个柱子做位置偏移、收窄宽度处理:
- 统一设置柱子宽度为
0.35 - 主Y轴柱子相对X坐标偏移
-0.2,次Y轴柱子偏移+0.2 - 保证两个柱子在同一X类别下并排展示,无遮挡
内容的提问来源于stack exchange,提问作者johnadem
相关产品推荐
相关产品推荐

