Matplotlib实现跨两个垂直子图绘制数据并添加共用右侧Y轴的方法
实现跨子图的曲线与共享右侧Y轴
嘿,我完全懂你的需求了——你不想让降水数据只绑定在第一个子图的右侧Y轴,而是要让它的曲线横跨上下两个子图,同时右侧的Y轴刻度从下方子图的底部一直延伸到上方子图的顶部对吧?这就给你搞定:
核心思路是创建一个自定义位置的坐标轴,让它的垂直范围刚好覆盖上下两个子图,然后在这个新轴上绘制降水数据,并把它的Y轴放在右侧。这样就能实现你要的跨图效果了。
下面是完整的可运行代码:
import matplotlib.pyplot as plt import numpy as np # 创建2行1列的子图,调整dpi方便预览(你可以改回600) fig, (ax_speed, ax_pos) = plt.subplots(2, 1, figsize=(20, 15), dpi=100) # ---------------------- 绘制第一个子图:Speed ---------------------- x = np.array([0, 1, 2, 3]) y_speed = np.array([3, 8, 1, 10]) ax_speed.plot(x, y_speed, label='speed', color='tab:blue') ax_speed.legend(loc='upper left') ax_speed.set_ylabel('Speed') # ---------------------- 绘制第二个子图:Position ---------------------- y_pos = np.array([3, 8, 1, 10]) ax_pos.plot(x, y_pos, label='position', color='tab:orange') ax_pos.legend(loc='upper left') ax_pos.set_ylabel('Position') ax_pos.set_xlabel('Time') # 只在最下方子图显示X轴标签 # ---------------------- 创建跨子图的坐标轴并绘制Precipitation ---------------------- # 获取两个子图的归一化位置参数(以整个画布为基准) pos_speed = ax_speed.get_position() pos_pos = ax_pos.get_position() # 计算跨图坐标轴的位置:左边界和子图对齐,底部是下方子图的底部,顶部是上方子图的顶部 # 格式:[left, bottom, width, height] cross_axis_pos = [ pos_speed.x0, # 左边界和上方子图一致 pos_pos.y0, # 底部和下方子图一致 pos_speed.width, # 宽度和子图一致 pos_speed.y1 - pos_pos.y0 # 高度=上方子图顶部 - 下方子图底部 ] ax_cross = fig.add_axes(cross_axis_pos) # 绘制降水数据 y_precip = np.array([10, 0, 4, 20]) ax_cross.plot(x, y_precip, label='precipitation', color='tab:green') ax_cross.legend(loc='upper right') ax_cross.set_ylabel('Precipitation') # 把Y轴移到右侧,并且设置标签在右侧 ax_cross.yaxis.tick_right() ax_cross.yaxis.set_label_position('right') # 隐藏跨图轴的X轴(避免和下方子图重复显示) ax_cross.set_xticks([]) ax_cross.set_xlabel('') # 确保三个轴的X轴范围完全一致 ax_cross.set_xlim(ax_speed.get_xlim()) plt.show()
关键细节解释:
- 自定义坐标轴位置:通过
get_position()获取子图的归一化坐标,精确计算出覆盖两个子图的区域,再用fig.add_axes()创建这个跨图轴。 - 右侧Y轴设置:用
yaxis.tick_right()和yaxis.set_label_position('right')把降水的Y轴移到右侧,刚好对齐两个子图的垂直范围。 - 避免重复元素:隐藏跨图轴的X轴刻度和标签,让下方子图的X轴作为唯一的时间轴显示。
这样运行后,降水曲线就会完美横跨两个子图,右侧的Y轴从下方子图的右下角(0刻度)一直延伸到上方子图的右上角(20刻度),完全符合你的需求。
内容的提问来源于stack exchange,提问作者Nihilum
相关产品推荐
相关产品推荐

