如何为Matplotlib的2×2子图添加双Y轴
解决方案
要给每个子图添加双Y轴,核心是用ax.twinx()创建次坐标轴,分别对应百分比(左Y轴)和完整数值(右Y轴),同时用柱状图展示数值型数据、折线图展示百分比数据,实现清晰对比。以下是修改后的完整代码:
import matplotlib.pyplot as plt # 假设x为时间/分类变量(比如数据索引,可根据实际情况调整) x = sales_dashboard_monthly_salesperson.index # 提取所需数据 x1 = sales_dashboard_monthly_salesperson['leads_per_rep'] x2 = sales_dashboard_monthly_salesperson['close_per_rep'] x3 = sales_dashboard_monthly_salesperson['num_deals_start'] x4 = sales_dashboard_monthly_salesperson['marked_won'] y1 = sales_dashboard_monthly_salesperson['close%'] # 创建2x2子图布局 fig, axs = plt.subplots(2, 2, figsize=(12, 10)) # ---------------------- 子图[0,0]:人均线索量 vs 成单率 ---------------------- ax = axs[0, 0] # 左Y轴:柱状图展示人均线索量 bar = ax.bar(x, x1, color='#1f77b4', alpha=0.6) ax.set_title('人均线索量 vs 成单率') ax.set_xlabel('时间/分类') ax.set_ylabel('人均线索量', color='#1f77b4') ax.tick_params(axis='y', labelcolor='#1f77b4') # 右Y轴:折线图展示成单率 ax_twin = ax.twinx() line = ax_twin.plot(x, y1, color='#ff7f0e', marker='o') ax_twin.set_ylabel('成单率(%)', color='#ff7f0e') ax_twin.tick_params(axis='y', labelcolor='#ff7f0e') # ---------------------- 子图[0,1]:人均成单量 vs 成单率 ---------------------- ax = axs[0, 1] # 左Y轴:柱状图展示人均成单量 bar = ax.bar(x, x2, color='#2ca02c', alpha=0.6) ax.set_title('人均成单量 vs 成单率') ax.set_xlabel('时间/分类') ax.set_ylabel('人均成单量', color='#2ca02c') ax.tick_params(axis='y', labelcolor='#2ca02c') # 右Y轴:折线图展示成单率 ax_twin = ax.twinx() line = ax_twin.plot(x, y1, color='#d62728', marker='s') ax_twin.set_ylabel('成单率(%)', color='#d62728') ax_twin.tick_params(axis='y', labelcolor='#d62728') # ---------------------- 子图[1,0]:启动交易数 vs 成单率 ---------------------- ax = axs[1, 0] # 左Y轴:柱状图展示启动交易数 bar = ax.bar(x, x3, color='#9467bd', alpha=0.6) ax.set_title('启动交易数 vs 成单率') ax.set_xlabel('时间/分类') ax.set_ylabel('启动交易数', color='#9467bd') ax.tick_params(axis='y', labelcolor='#9467bd') # 右Y轴:折线图展示成单率 ax_twin = ax.twinx() line = ax_twin.plot(x, y1, color='#8c564b', marker='^') ax_twin.set_ylabel('成单率(%)', color='#8c564b') ax_twin.tick_params(axis='y', labelcolor='#8c564b') # ---------------------- 子图[1,1]:已赢单量 vs 成单率 ---------------------- ax = axs[1, 1] # 左Y轴:柱状图展示已赢单量 bar = ax.bar(x, x4, color='#e377c2', alpha=0.6) ax.set_title('已赢单量 vs 成单率') ax.set_xlabel('时间/分类') ax.set_ylabel('已赢单量', color='#e377c2') ax.tick_params(axis='y', labelcolor='#e377c2') # 右Y轴:折线图展示成单率 ax_twin = ax.twinx() line = ax_twin.plot(x, y1, color='#7f7f7f', marker='*') ax_twin.set_ylabel('成单率(%)', color='#7f7f7f') ax_twin.tick_params(axis='y', labelcolor='#7f7f7f') # 自动调整子图间距,避免标签重叠 fig.tight_layout() plt.show()
关键修改说明
- 每个子图通过
ax.twinx()创建独立次Y轴,解决百分比与数值数据刻度范围不匹配的问题 - 统一用柱状图展示完整数值、折线图展示百分比,视觉区分清晰
- 给每个轴设置对应颜色的标签和刻度,提升可读性
- 替换默认标题与轴标签为业务相关文本,增强图表实用性
- 添加
fig.tight_layout()自动优化子图布局,避免元素重叠
内容的提问来源于stack exchange,提问作者austinthompson
相关产品推荐
相关产品推荐

