Matplotlib多子图共享Y轴:如何仅让部分子图实现Y轴共享?
解决方案:让前N-1个子图共享Y轴,最后一个独立
方法一:分两步创建子图
先创建前N-1个共享Y轴的子图,再单独添加最后一个独立子图,代码示例:
import matplotlib.pyplot as plt import numpy as np total_subplots = 4 # 总子图数,前3个共享Y轴,第4个独立 # 创建前3个共享Y轴的子图 fig, axes = plt.subplots(nrows=total_subplots-1, sharey=True) # 处理单个子图的情况(避免axes不是列表) if total_subplots-1 == 1: axes = [axes] # 添加最后一个独立子图 axes.append(fig.add_subplot(total_subplots, 1, total_subplots)) # 测试绘图 x = np.linspace(0, 10, 100) for ax in axes[:-1]: ax.plot(x, np.sin(x)) axes[-1].plot(x, np.cos(x)*10) # 最后一个子图Y轴范围独立 plt.tight_layout() plt.show()
方法二:创建时指定共享关系
逐个创建子图,让前N-1个子图都绑定到第一个子图的Y轴,最后一个单独创建:
import matplotlib.pyplot as plt import numpy as np total_subplots = 4 fig = plt.figure() # 第一个子图作为共享基准 ax_base = fig.add_subplot(total_subplots, 1, 1) axes = [ax_base] # 创建中间子图,全部共享基准子图的Y轴 for idx in range(1, total_subplots-1): ax = fig.add_subplot(total_subplots, 1, idx+1, sharey=ax_base) axes.append(ax) # 添加最后一个独立子图 axes.append(fig.add_subplot(total_subplots, 1, total_subplots)) # 测试绘图 x = np.linspace(0, 10, 100) for ax in axes[:-1]: ax.plot(x, np.sin(x)) axes[-1].plot(x, np.cos(x)*10) plt.tight_layout() plt.show()
你之前方法的问题分析
方法1:
plt.subplots(sharey=True)会让所有子图强制共享Y轴,无法排除最后一个,不符合需求,这个你已经判断正确。方法2:报错
ValueError: y-axis is already shared是因为sharey()是双向绑定操作,当你第一次执行axes[0].sharey(axes[1])后,axes[1]的Y轴已经和axes[0]绑定共享了,再次对其他子图调用这个方法时,会触发重复绑定的错误。正确的做法是每个子图只需要和基准子图绑定一次,或者在创建时就指定共享关系。方法3:两两共享会导致共享的主从关系混乱。比如
ax0.sharey(ax1)会让ax0的Y轴范围跟随ax1,而ax1.sharey(ax2)又让ax1跟随ax2,最终只有最后一个被两两绑定的子图范围会生效,导致前面的子图范围无法同步。统一绑定到同一个基准子图才能保证所有共享子图的Y轴范围同步。
内容的提问来源于stack exchange,提问作者Ilya
相关产品推荐
相关产品推荐

