Предполагая, что spinmob
фактически использует scipy.curve_fit
под капотом, я бы предположил (извините), что проблема в том, что начальные значения, которые вы ему задаете, настолько далеки, что он не может найти решение.
Конечно, A=1
не очень хорошая догадка для scipy.curve_fit()
или spinmob.fitter()
.Пик определенно отрицателен, и вы должны угадать значение, больше похожее на -0.1
, чем +1
.На самом деле вы, вероятно, могли бы утверждать, что A
должно быть <0. </p>
Начальное значение 7,688 для mu
, которое вы задаете для curve_fit()
, довольно хорошее и позволитрешение.Я не знаю, является ли это опечаткой или нет, но начальное значение 8,688 для mu
, которое вы задаете для spinmob.fitter()
, очень далеко (то есть выходит за пределы диапазона данных), и подгонка никогда не будетможет уточнить свой путь к правильному решению оттуда.
Начальные значения имеют значение для подбора кривой, и плохие начальные значения могут привести к плохим результатам.
Некоторые могут рассматривать его как бесстыдный плагин, но позвольте мне призвать вас попробовать lmfit
(https://lmfit.github.io/lmfit-py/) (я ведущий автор) для решения этой проблемы. Lmfit заменяетмассив значений параметров с именованными объектами Parameter для лучшей организации подгонок. Он также имеет встроенную гауссову модель (которая также рассчитывает FWHM, включая неопределенность). То есть, с Lmfit ваш скрипт может выглядеть так:
import numpy as np
import matplotlib.pyplot as plt
from lmfit.models import GaussianModel
from lmfit.lineshapes import gaussian
# create fake data that looks like yours
xdata = 7.670 + np.arange(41)*0.0010
ydata = gaussian(xdata, amplitude=-0.196, center=7.6881, sigma=0.001)
ydata += np.random.normal(size=41, scale=10.0)
# create gaussian model
gmodel = GaussianModel()
# fit data, giving initial values for amplitude, center, and sigma
result = gmodel.fit(ydata, x=xdata, amplitude=-0.1, center=7.688, sigma=0.005)
# show results
print(result.fit_report())
plt.plot(xdata, ydata, 'bo', label='data')
plt.plot(xdata, result.best_fit, 'r+-', label='fit')
plt.legend()
plt.show()
Это распечатает отчет как
[Model]]
Model(gaussian)
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 21
# data points = 41
# variables = 3
chi-square = 5114.87632
reduced chi-square = 134.602009
Akaike info crit = 203.879794
Bayesian info crit = 209.020510
[[Variables]]
sigma: 9.7713e-04 +/- 1.5456e-04 (15.82%) (init = 0.005)
center: 7.68822727 +/- 1.5484e-04 (0.00%) (init = 7.688)
amplitude: -0.19273945 +/- 0.02643400 (13.71%) (init = -0.1)
fwhm: 0.00230096 +/- 3.6396e-04 (15.82%) == '2.3548200*sigma'
height: -78.6917624 +/- 10.7894236 (13.71%) == '0.3989423*amplitude/max(1.e-15, sigma)'
[[Correlations]] (unreported correlations are < 0.100)
C(sigma, amplitude) = -0.577
и даст график данных и лучше всего подойдет как
, который должен бытьблизко к тому, что вы пытаетесь сделать.