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

Matplotlib subplot中sharex与set_xlim参数兼容性问题

问题成因

当sharex=True时,matplotlib会强制绑定所有子图的x轴属性,包括显示范围、刻度定位规则、格式化规则,所有子图的x轴状态会以最后一次修改轴属性的子图设置为准。
原有代码在循环中逐个给三个子图单独调用set_xlim、设置刻度定位器和时间格式化器:obspy的UTCDateTime转pandas时间对象时存在浮点精度误差,哪怕是经过同一参数trim的波形,三个通道单独计算出的limin/limax也会有微秒到毫秒级的差异。共享轴模式下,每次给单个子图设置xlim都会同步修改所有子图的x轴范围,重复设置刻度规则还会触发重绘冲突,最终matplotlib的自动缩放逻辑会判定前两个子图无有效显示内容,将绘图区域压缩为不可见的细线,表现为子图消失。

正确实现方案
  • 开启sharex=True后,不需要在循环中给每个子图重复设置x轴范围、刻度属性,仅需给任意一个子图设置一次,所有共享轴会自动同步配置,matplotlib也会自动隐藏上方子图的x轴刻度标签,无需手动调整
  • 提前统一计算一次x轴的上下界,不要逐通道单独计算,从根源避免浮点精度导致的范围冲突
  • 不要用globals()动态创建变量存储标签,直接用列表统一存储即可,代码可读性更高

修正后的核心代码如下:

st.trim(starttime=t0, endtime=(t0+float(dur)), nearest_sample=True)
tr3 = st.copy()
tr3.filter("bandpass", freqmin=float(flow), freqmax=float(fhigh), corners=4, zerophase=True)

# 统一生成通道标签
labels = []
for tr in tr3:
    labels.append(f"{tr.stats.network}.{tr.stats.station}.{tr.stats.location}.{tr.stats.channel}")

# 开启x轴共享
fig, ax = plt.subplots(3,1,sharex=True,sharey=False,figsize=(18,10), dpi=200)

# 提前统一计算x轴显示范围,避免逐子图设置的精度误差
x_min = pd.to_datetime(str(tr3[0].stats.starttime))
x_max = pd.to_datetime(str(tr3[0].stats.endtime))

for idx in range(3):
    ax[idx].plot(tr3[idx].times(("utcdatetime")), tr3[idx].data, 'r', label=labels[idx])
    ax[idx].xaxis.grid(True, which='major', color='k', linestyle='dotted', linewidth=0.5)
    ax[idx].yaxis.grid(True, which='major', color='k', linestyle='dotted', linewidth=0.5)
    ax[idx].legend(loc='upper left', ncol=4)

# 仅需设置一次x轴属性,所有共享子图自动同步
ax[-1].set_xlim(x_min, x_max)
ax[-1].xaxis.set_major_formatter(mdates.DateFormatter('%H:%M:%S'))
ax[-1].xaxis.set_major_locator(mdates.SecondLocator())

fig.suptitle('Évènement du '+str(date)+'T'+str(hr)+' station : '+str(sta))

注:如果三个通道trim后存在极短的时间差,统一使用第一个/最后一个通道的时间范围作为全局x轴范围不会影响波形显示,微秒级的差异肉眼完全无法识别

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.02 04:01:23