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

Matplotlib与lmfit拟合曲线X轴过度压缩问题排查

拟合曲线X轴异常压缩问题求助

数据情况

foci_red   fold_dil
0   0.986947      20.0
1   0.947788      60.0
2   0.908629     180.0
3   0.765047     540.0
4   0.660624    1620.0
5   0.216824    4860.0
6   0.060189   14580.0
7   0.112400   43740.0
8  -0.148658  131220.0
9  -0.070341  393660.0
10  0.960841      20.0
11  0.869471      60.0
12  0.830312     180.0
13  0.673677     540.0
14  0.490935    1620.0
15  0.373459    4860.0
16 -0.005076   14580.0
17  0.047136   43740.0
18  0.138506  131220.0
19 -0.096447  393660.0
20  0.960841      20.0
21  0.869471      60.0
22  0.895577     180.0
23  0.738941     540.0
24  0.321247    1620.0
25  0.334300    4860.0
26  0.086294   14580.0
27  0.060189   43740.0
28 -0.109500  131220.0
29  0.086294  393660.0

拟合函数定义

def func(x, u, s, l, i): 
    return ((l-u)/(1.0+((x/i)**s))) + u

参数设置与拟合过程

import lmfit
import numpy as np

init_model = lmfit.Model(func)
# 初始值参考Results.rmd:Theta1(upper)=1, Theta3(Slope)=-1, Theta4(lower)=0
params_pog = init_model.make_params()
params_pog.add('u', value=1, min=0.95, max=1.05)
params_pog.add('i', value=50, min=-np.inf, max=np.inf)
params_pog.add('s', value=-1, min=-1.3, max=-0.7)
params_pog.add('l', value=0, min=-0.05, max=0.05)

拟合结果

[[Model]]
    Model(func)
[[Fit Statistics]]
    # fitting method   = Nelder-Mead
    # function evals   = 790
    # data points      = 30
    # variables        = 4
    chi-square         = 0.18783349
    reduced chi-square = 0.00722437
    Akaike info crit   = -144.201903
    Bayesian info crit = -138.597114
    R-squared          = 0.96014230
  Warning: uncertainties could not be estimated:
    this fitting method does not natively calculate uncertainties
    and numdifftools is not installed for lmfit to do this. Use
    `pip install numdifftools` for lmfit to estimate uncertainties
    with this fitting method.
[[Variables]]
    u:  0.96936837 (init = 1)
    s: -0.88999854 (init = -1)
    l: -0.03939795 (init = 0)
    i:  1952.96706 (init = 50)

绘图问题

使用Matplotlib绘制时,曲线在X轴异常压缩,代码如下:

import matplotlib.pyplot as plt

plt.style.use(['science', 'notebook', 'grid'])

fig1 = plt.figure()
fig1, ax = plt.subplots(2)

axes = ax[0]
axes.set_xscale('log')

axes.scatter(janfd, janfr)
axes.plot(func(janfd, 0.96936837, -0.88999854, -0.03939795, 1952.96706), scalex=True)

拟合的R²值较高,参数符合预期,但曲线无法覆盖所有原始数据点,不确定是绘图方式还是X轴缩放问题。


问题解决

问题出在plot函数的调用逻辑上:

  1. 当前代码仅传入拟合后的y值,未指定对应的x轴数据,Matplotlib默认用0、1、2...作为x坐标,而非原始的janfd(log缩放的x值),导致曲线被压缩。
  2. 原始x数据janfd存在重复值,直接用它绘图会导致曲线跳跃,建议生成一组log轴上均匀分布的x值来绘制平滑曲线。

修正后的绘图代码:

import matplotlib.pyplot as plt
import numpy as np

plt.style.use(['science', 'notebook', 'grid'])

# 创建子图
fig1, ax = plt.subplots(2)
axes = ax[0]
axes.set_xscale('log')

# 绘制原始数据散点
axes.scatter(janfd, janfr, label='原始数据')

# 生成用于绘制曲线的x值:在log空间均匀取点,覆盖数据的x范围
x_min = janfd.min()
x_max = janfd.max()
x_curve = np.logspace(np.log10(x_min), np.log10(x_max), 100)  # 100个点足够平滑

# 计算拟合曲线的y值
y_curve = func(x_curve, 0.96936837, -0.88999854, -0.03939795, 1952.96706)

# 绘制拟合曲线
axes.plot(x_curve, y_curve, color='red', label='拟合曲线')

# 添加图例、标签
axes.set_xlabel('fold_dil')
axes.set_ylabel('foci_red')
axes.legend()

plt.show()

额外提示:

  • 安装numdifftools可解决拟合结果无法估算参数不确定性的问题:pip install numdifftools
  • 若已保存拟合结果对象(如result = init_model.fit(janfr, params_pog, x=janfd)),可直接用lmfit自带方法绘图:
    result.plot(ax=axes)
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 13:05:17