You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Matplotlib多子图中绘制共用水平线且保持子图间距不变

实现三个子图共用一条完整水平线(保留子图间距)

要让三个子图共享一条连贯的底部水平线,同时不改变它们之间的原有间距,最靠谱的方法是基于整个画布的坐标系来绘制这条线,而非在单个子图内操作。这样就能完美填充子图间的空隙,形成一条完整的长水平线。

修改后的完整代码

import numpy as np
import matplotlib.pyplot as plt

x_axis=['HE','BBHE','BHEPL','DOTHE','RSIHE','QDHE','RSWHE']
y_drive=[0.480,0.478,0.638,0.508,0.475,0.587,0.846]
y_stare=[0.759,0.766,0.856,0.659,0.777,0.767,0.865]
y_chase=[0.482,0.515,0.809,0.763,0.520,0.802,0.802]

x=np.arange(0,7)
width=1

fig,(ax1,ax2,ax3)=plt.subplots(1,3,sharey=True,sharex=True)

# 绘制第一个子图
ax1.bar(x,y_drive,width,color=['r','g','b','c','m','y','k'],alpha=0.80)
ax1.spines['top'].set_visible(False)
ax1.spines['right'].set_visible(False)
ax1.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False)
ax1.set_xlabel('DRIVE')
ax1.set_ylim(0,1)

# 绘制第二个子图
ax2.bar(x,y_stare,width,color=['r','g','b','c','m','y','k'],alpha=0.80)
ax2.spines['top'].set_visible(False)
ax2.spines['left'].set_visible(False)
ax2.spines['right'].set_visible(False)
ax2.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False)
ax2.set_xlabel('STARE')

# 绘制第三个子图
ax3.bar(x,y_chase,width,color=['r','g','b','c','m','y','k'],alpha=0.80)
ax3.spines['top'].set_visible(False)
ax3.spines['left'].set_visible(False)
ax3.spines['right'].set_visible(False)
ax3.tick_params(axis='both',which='both',bottom=False,left=False,labelbottom=False)
ax3.set_xlabel('CHASE')

# ----------------关键新增代码----------------
# 获取子图在画布上的相对位置(坐标范围0-1,0对应最左/最下,1对应最右/最上)
left_edge = ax1.get_position().x0  # 第一个子图的左边缘
right_edge = ax3.get_position().x1 # 第三个子图的右边缘
bottom_y = ax1.get_position().y0   # 子图底部的y坐标(因sharey,三个子图底部高度一致)

# 在画布坐标系下绘制横跨所有子图的水平线
fig.plot([left_edge, right_edge], [bottom_y, bottom_y], color='black', linewidth=2)
# -------------------------------------------

plt.show()

关键逻辑说明

  • get_position()能获取子图在画布上的相对位置,用这个坐标系绘制的元素可以跨子图显示
  • 取第一个子图的左边缘和第三个子图的右边缘作为水平线的起止点,既能覆盖所有子图,又能保留它们之间的空隙
  • 水平线的y坐标和子图底部对齐,保证视觉上和子图边缘连贯
  • 使用fig.plot()而非子图的plot()方法,前者是基于整个画布的坐标系操作,能完美实现跨子图的线条

这样修改后,你就能得到一条连贯横跨三个子图的水平线,同时子图之间的间距完全保持原有状态~

内容的提问来源于stack exchange,提问作者Navdeep

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:27:17