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函数的调用逻辑上:
- 当前代码仅传入拟合后的y值,未指定对应的x轴数据,Matplotlib默认用0、1、2...作为x坐标,而非原始的
janfd(log缩放的x值),导致曲线被压缩。 - 原始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
相关产品推荐
相关产品推荐

