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

Matplotlib中基于np.interp实现的次级X轴范围设置及轴值匹配问题

Matplotlib中基于np.interp实现的次级X轴范围设置及轴值匹配问题

嗨,我来帮你解决这个双X轴的问题!你的核心问题在于两个X轴数据完全独立,而默认的secondary_xaxis结合np.interp时,matplotlib的自动刻度逻辑会生成超出你数据范围的刻度,同时设置主轴范围后没有同步调整次级轴的范围匹配规则。下面分两步解决你的问题:

一、移除次级轴上多余的0和3e-28刻度

出现这个问题的原因是:matplotlib的自动刻度生成器会尝试覆盖比你的实际数据范围更广的区间,而np.interp在输入超出原始xold范围时,会返回边界值(比如x小于20时返回xnew[0],x大于120时返回xnew[-1]),但这些边界外的刻度并不是你需要的。

解决方案:让转换函数在超出数据范围时返回NaN

修改你的forward和inverse函数,当输入值超出原始数据的范围时返回NaN,这样matplotlib会忽略这些无效值,不会生成多余的刻度:

import matplotlib.pyplot as plt
import numpy as np

fig, ax = plt.subplots(constrained_layout=True)

x_upper = np.array([2.379618e-29,5.895669e-29,1.018725e-28,
1.413803e-28,1.780809e-28,2.080620e-28,
2.287013e-28,2.603605e-28,2.810124e-28])
x_lower = np.array([20,30,40,50,60,70,80,100,120])
y = np.array([-1.333526e-16,-8.841676e-16,-2.803599e-15,
-5.300285e-15,-7.723194e-15,-9.906261e-15,
-1.124626e-14,-1.238456e-14,-1.193596e-14])

ax.plot(x_lower, y)

xold = x_lower
xnew = x_upper

def forward(x):
    # 仅在xold的范围内进行插值,超出范围返回NaN
    mask = (x >= xold.min()) & (x <= xold.max())
    result = np.full_like(x, np.nan)
    result[mask] = np.interp(x[mask], xold, xnew)
    return result

def inverse(x):
    # 仅在xnew的范围内进行插值,超出范围返回NaN
    mask = (x >= xnew.min()) & (x <= xnew.max())
    result = np.full_like(x, np.nan)
    result[mask] = np.interp(x[mask], xnew, xold)
    return result

secax = ax.secondary_xaxis('top', functions=(forward,inverse))
plt.autoscale(enable=True, axis='x', tight=True)
plt.show()

替代方案:手动设置次级轴刻度

如果你希望次级轴只显示你提供的x_upper数值,可以直接手动设置刻度:

# 在创建secax之后添加这一行
secax.set_xticks(x_upper)

这样次级轴就只会显示你的数据点对应的刻度值,彻底避免多余刻度。

二、解决主轴范围修改后轴值不匹配的问题

当你设置ax.set_xlim(15, 125)时,主轴范围超出了x_lower的原始范围(20-120),但secondary_xaxis不会自动调整转换逻辑的有效范围,导致两个轴的刻度无法对应。

解决方案:同步主副轴的有效范围

你需要确保主轴的范围被限制在x_lower的有效区间内,或者手动将次级轴的范围同步到主轴范围对应的转换值:

方法1:限制主轴范围在数据范围内

# 主轴范围设置为x_lower的最小和最大值,这样次级轴自然匹配x_upper的范围
ax.set_xlim(xold.min(), xold.max())

方法2:手动计算并设置次级轴范围(当主轴必须超出数据范围时)

如果一定要设置主轴范围为(15,125),那么需要手动计算对应的次级轴范围,并确保转换函数在有效区间外返回NaN:

ax.set_xlim(15, 125)
# 计算主轴范围对应的次级轴有效范围
secax.set_xlim(forward(xold.min()), forward(xold.max()))

这样次级轴的刻度只会在x_upper的范围内生成,主轴超出部分(15-20)对应的次级轴没有刻度,避免不匹配的问题。

经过这些调整后,你的双X轴就能正确显示,且不会出现多余的刻度和值不匹配的情况啦!

备注:内容来源于stack exchange,提问作者Hyperbolic

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.04.20 06:18:03