如何堆叠3个共享X轴且含多Y轴(twinx)的Matplotlib子图?
解决Matplotlib多子图堆叠共享X轴并使用twinx的问题
我来帮你搞定这个Matplotlib子图堆叠的问题!下面是一套完整的解决方案,亲测好用:
核心思路
- 用
plt.subplots创建共享X轴的3个子图,确保缩放和X轴范围同步 - 对需要双Y轴的子图调用
twinx()创建第二个独立Y轴 - 隐藏前两个子图的X轴刻度和标签,只保留最后一个子图的X轴信息
- 调整布局避免标签重叠,合并双Y轴的图例,让图表更清晰
完整代码示例
import matplotlib.pyplot as plt import numpy as np # 生成示例数据(你可以替换成自己的真实数据) x = np.linspace(0, 10, 100) y1 = np.sin(x) y2 = np.cos(x) * 10 y3 = np.tan(x/2) y4 = np.exp(x/5) / 10 y5 = np.log(x+1) # 创建3个垂直堆叠、共享X轴的子图,figsize可按需调整 fig, (ax1, ax2, ax3) = plt.subplots(3, 1, figsize=(8, 10), sharex=True) # ---------------------- 第一个子图(双Y轴) ---------------------- ax1.plot(x, y1, color='blue', label='Sin(x)') ax1.set_ylabel('Sin(x)', color='blue') ax1.tick_params(axis='y', labelcolor='blue') # 创建第一个子图的双Y轴 ax1_twin = ax1.twinx() ax1_twin.plot(x, y2, color='red', label='10*Cos(x)') ax1_twin.set_ylabel('10*Cos(x)', color='red') ax1_twin.tick_params(axis='y', labelcolor='red') # 合并两个Y轴的图例,避免重复显示 lines1, labels1 = ax1.get_legend_handles_labels() lines2, labels2 = ax1_twin.get_legend_handles_labels() ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper right') # ---------------------- 第二个子图(双Y轴) ---------------------- ax2.plot(x, y3, color='green', label='Tan(x/2)') ax2.set_ylabel('Tan(x/2)', color='green') ax2.tick_params(axis='y', labelcolor='green') ax2_twin = ax2.twinx() ax2_twin.plot(x, y4, color='purple', label='Exp(x/5)/10') ax2_twin.set_ylabel('Exp(x/5)/10', color='purple') ax2_twin.tick_params(axis='y', labelcolor='purple') # 合并图例 lines3, labels3 = ax2.get_legend_handles_labels() lines4, labels4 = ax2_twin.get_legend_handles_labels() ax2.legend(lines3 + lines4, labels3 + labels4, loc='upper right') # ---------------------- 第三个子图(单Y轴,可扩展为双Y轴) ---------------------- ax3.plot(x, y5, color='orange', label='Log(x+1)') ax3.set_xlabel('X Axis') # 仅最后一个子图显示X轴标签 ax3.set_ylabel('Log(x+1)', color='orange') ax3.tick_params(axis='y', labelcolor='orange') ax3.legend(loc='upper right') # ---------------------- 隐藏前两个子图的X轴 ---------------------- # 完全隐藏刻度线和标签 ax1.tick_params(axis='x', which='both', bottom=False, labelbottom=False) ax2.tick_params(axis='x', which='both', bottom=False, labelbottom=False) # 调整子图间距,避免标签重叠 plt.tight_layout() plt.show()
关键要点解析
- 共享X轴:
sharex=True参数让三个子图的X轴完全同步,缩放、平移时都会一起变化,不用手动对齐 - 双Y轴处理:
twinx()会创建一个和原X轴共享、但Y轴独立的轴,分别设置颜色和标签能提升可读性 - 隐藏X轴:
tick_params里的bottom=False隐藏刻度线,labelbottom=False隐藏刻度标签,which='both'确保主副刻度都隐藏 - 图例合并:双Y轴的图例需要手动合并两个轴的手柄和标签,不然只会显示其中一个轴的图例
- 布局调整:
tight_layout()自动优化子图间距,避免Y轴标签、标题互相遮挡
内容的提问来源于stack exchange,提问作者Sarah A Smythe
相关产品推荐
相关产品推荐

