Water Teixeira ∗ Resolution with lmfit
Introduction
This example shows how to use the water_teixeira model and fit the data using lmfit.
The data are two sets of water data measured at IN5 (ILL) at 5 Å.
Reference: J. Qvist, H. Schober and B. Halle, J. Chem. Phys. 134, 144508 (2011)
Physical units
For information about unit conversion, please refer to the jupyter notebook called Convert_units.ipynb in the tools folder.
Import libraries
[1]:
import h5py
from scipy.integrate import simps
import numpy as np
import matplotlib.pyplot as plt
# the following line is to remove the warning about too many figures open simultaneously
plt. rcParams.update({'figure.max_open_warning': 0})
import lmfit
from scipy.interpolate import interp1d
%matplotlib widget
Setting of fitting
Import reference data
[2]:
path_to_data = './data/'
with h5py.File(path_to_data + 'H2O_293K_5A.hdf', 'r') as f:
data_in = f['entry1']
w = data_in['data1']
x = w['X'][()] # energy or time values
unit_w = w['X'].attrs['long_name']
unit_q = w['Y'].attrs['long_name']
y = w['DATA'][()] # intensities
e = w['errors'][()] # errors for the intensities
# Obtain the momentum transfer values
q = w['Y'][()]
data_5A = dict(q=q, x=x, y=y, e=e)
[3]:
# number of spectra (i.e. number of different q-values)
nb_q_values = len(data_5A['q'])
Display units of input data
Just for information in order to determine if a conversion of units is required before using the QENSmodels
[4]:
print((f"The names and units of `w` (`x`axis) and `q` are: "
f"{unit_w[0].decode()} and {unit_q[0].decode()}, respectively."))
The names and units of `w` (`x`axis) and `q` are: Energy Transfer (meV) and Wavevector Transfer (A!U-1!N), respectively.
Import resolution data and normalize (unit area)
[5]:
path_to_data = './data/'
with h5py.File(path_to_data + 'V_273K_5A.hdf', 'r') as f:
data = f['entry1']
w = data['data1']
res_5A_x = w['X'][()]
res_5A = np.transpose(w['DATA'][()])
# Force resolution function to have unit area
for i in range(len(data_5A['q'])):
area = simps(res_5A[:,i], data_5A['x'])
res_5A[:,i] /= area
Mask data according to energy range and filter negative error
[6]:
# Filter according to energy-range
mask = np.intersect1d(np.where(data_5A['x']>-1.), np.where(data_5A['x']<1.))
f_5A_mask = dict()
f_5A_mask['x'] = np.asarray([data_5A['x'][mask] for i in range(nb_q_values)])
f_5A_mask['y'] = np.asarray([y[mask] for y in data_5A['y']])
f_5A_mask['e'] = np.asarray([e[mask] for e in data_5A['e']])
# Select resolution according to energy range
res_5A_x = res_5A_x[mask]
res_5A = res_5A[mask, :]
[7]:
# Filter according to negative error values
# resolution
selected_indices = np.where(f_5A_mask['e'][i] > 0.0)
resol_5A_x = np.asarray([res_5A_x[selected_indices] for i in range(nb_q_values)])
resol_5A = np.asarray([res_5A[selected_indices, i][0] for i in range(nb_q_values)])
# data
f_5A = dict()
f_5A['x'] = np.asarray([x[selected_indices] for i, x in enumerate(f_5A_mask['x'])])
f_5A['y'] = np.asarray([y[selected_indices] for i, y in enumerate(f_5A_mask['y'])])
f_5A['e'] = np.asarray([e[selected_indices] for i, e in enumerate(f_5A_mask['e'])])
[8]:
# plot experimental data
fig0= plt.figure()
[plt.semilogy(f_5A['x'][i], f_5A['y'][i]) for i in range(nb_q_values)]
plt.xlabel(r'Energy transfer (meV)')
plt.title('Reference data - 5 Angstrom')
plt.grid();
[9]:
# plot experimental data
fig1 = plt.figure()
[plt.semilogy(resol_5A_x[i], resol_5A[i]) for i in range(nb_q_values)]
plt.xlabel(r'Energy transfer (meV)')
plt.title('Resolution function - 5 Angstrom')
plt.grid();
Create function for instrument resolution data (cubic interpolation between tabulated data points)
[10]:
f_interp = [interp1d(resol_5A_x[i],
resol_5A[i]/np.sum(resol_5A[i]),
kind='cubic',
bounds_error=False,
fill_value='extrapolate') for i in range(nb_q_values)]
def irf_gate(w, spectrum_nb=0):
""" Function defined from the interpolation of instrument resolution data
Used to define fitting model and plot """
return f_interp[spectrum_nb](w)
[11]:
# check interpolation for first spectrum of resolution function: plot tabulated data and interpolated data
indx = 0
fig2 = plt.figure()
plt.plot(resol_5A_x[indx],
resol_5A[indx]/np.sum(resol_5A[indx]),
'.',
label=f"tabulated data. q={data_5A['q'][indx]:.2}")
plt.plot(f_5A['x'][indx],
irf_gate(f_5A['x'][indx], indx),
'--',
label=f"extrapolated data. q={data_5A['q'][indx]:.2}")
plt.legend(bbox_to_anchor=(1.0, .95))
plt.xlabel('w')
plt.title(f'Instrument resolution: tabulated data and interpolated data for spectrum {indx}')
plt.grid();
Create fitting model
[12]:
import QENSmodels
[13]:
# Create convolution function
# code from https://lmfit.github.io/lmfit-py/model.html
def convolve(arr, kernel):
# simple convolution of two arrays
npts = min(len(arr), len(kernel))
pad = np.ones(npts)
tmp = np.concatenate((pad*arr[0], arr, pad*arr[-1]))
out = np.convolve(tmp, kernel, mode='valid')
noff = int((len(out) - npts)/2)
return out[noff:noff+npts]
[14]:
model = lmfit.CompositeModel(lmfit.Model(irf_gate), lmfit.Model(QENSmodels.sqwWaterTeixeira), convolve)
print(f'Names of parameters: {model.param_names}\nIndependent variable(s): {model.independent_vars}')
# Define boundaries for parameters to be refined
model.set_param_hint('scale', min=0, max=100)
model.set_param_hint('center', min=-0.1, max=0.1)
model.set_param_hint('D', min=0.05, max=0.25)
model.set_param_hint('resTime', min=0, max=1)
model.set_param_hint('radius', min=0.9, max=1.1)
model.set_param_hint('DR', min=0, max=1)
# Fix some of the parameters
model.set_param_hint('q', vary=False)
model.set_param_hint('spectrum_nb', vary=False)
params = model.make_params()
Names of parameters: ['spectrum_nb', 'q', 'scale', 'center', 'D', 'resTime', 'radius', 'DR']
Independent variable(s): ['w']
[15]:
# Plot of the fitting models without and convoluted with the resolution function
# The values of the parameters are specified below. Therefore they could be
#different from those used in the fitting.
fig3, ax3 = plt.subplots(1, 2)
# First subplot
for i in range(nb_q_values):
xx = f_5A['x'][i]
ax3[0].plot(xx,
QENSmodels.sqwWaterTeixeira(xx,
data_5A['q'][i],
scale=1,
center=0,
D=1,
resTime=1,
radius=1,
DR=1),
label=f"q={data_5A['q'][i]:.2}")
ax3[0].grid(True)
ax3[0].set(xlabel='Omega', ylabel='S(Q,w)', xlim=(-1, 1), title='No resolution')
ax3[0].tick_params()
plt.tight_layout(rect=[0, 0, 1, 0.8])
ax3[0].legend(bbox_to_anchor=(0., 1.1, 2., 0.102),
loc='lower right',
ncol=5,
mode="expand",
borderaxespad=0.,
fontsize=8)
# Second subplot
for i in range(nb_q_values):
params_plot = model.make_params(nb_spectrum=i,
q=data_5A['q'][i],
scale=10.,
center=0.,
D=0.13,
resTime=0.1,
radius=1.,
DR=0.3)
xx = f_5A['x'][i]
ax3[1].plot(xx, model.eval(params_plot, w=xx))
ax3[1].grid(True)
ax3[1].set(xlabel='w',
ylabel='R $\otimes$ S(Q,w)',
xlim=(-1,1),
title='Convoluted with resolution')
ax3[1].tick_params();
Running the fit using lmfit
[16]:
ini_values = {'scale': 10.,
'center': 0.,
'D': 0.13,
'resTime': 0.1,
'radius': 1.,
'DR': 0.3}
result_fit = [None,] * nb_q_values # store fits for all spectra
for i in range(nb_q_values):
params = model.make_params(nb_spectrum=i,
q=data_5A['q'][i],
scale=ini_values['scale'],
center=ini_values['center'],
D=ini_values['D'],
resTime=ini_values['resTime'],
radius=ini_values['radius'],
DR=ini_values['DR'])
# Q-independent parameters
if i==0:
D_value = params['D'].value
resTime_value = params['resTime'].value
radius_value = params['radius'].value
DR_value = params['DR'].value
else:
params['D'].set(value=D_value)
params['resTime'].set(value=resTime_value)
params['radius'].set(value=radius_value)
params['DR'].set(value=DR_value)
result_fit[i] = model.fit(f_5A['y'][i],
params,
w=f_5A['x'][i])
Showing the results
using methods implemented in lmfit
[17]:
# display result
for i in range(nb_q_values):
print(f'Result of fit {i}:\n', result_fit[i].fit_report())
Result of fit 0:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 52
# data points = 79
# variables = 6
chi-square = 11467.0423
reduced chi-square = 157.082771
Akaike info crit = 405.244972
Bayesian info crit = 419.461659
R-squared = 0.73497818
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 0.5 (fixed)
scale: 10.00000000 (init = 10)
center: 6.0081e-04 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000001 (init = 1)
DR: 0.00124601 (init = 0.3)
Result of fit 1:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 92
# data points = 79
# variables = 6
chi-square = 8833.44421
reduced chi-square = 121.006085
Akaike info crit = 384.631341
Bayesian info crit = 398.848028
R-squared = 0.72518801
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 0.6 (fixed)
scale: 10.00000000 (init = 10)
center: 2.1176e-05 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 5.9931e-07 (init = 0.3)
Result of fit 2:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 39
# data points = 79
# variables = 6
chi-square = 7795.91154
reduced chi-square = 106.793309
Akaike info crit = 374.760642
Bayesian info crit = 388.977329
R-squared = 0.67503269
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 0.7 (fixed)
scale: 10.00000000 (init = 10)
center: -0.01154662 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 0.02641266 (init = 0.3)
Result of fit 3:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 97
# data points = 79
# variables = 6
chi-square = 5842.27533
reduced chi-square = 80.0311690
Akaike info crit = 351.970793
Bayesian info crit = 366.187480
R-squared = 0.68088450
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 0.8 (fixed)
scale: 10.00000000 (init = 10)
center: -0.00397467 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 5.6541e-06 (init = 0.3)
Result of fit 4:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 39
# data points = 79
# variables = 6
chi-square = 4853.25408
reduced chi-square = 66.4829326
Akaike info crit = 337.318591
Bayesian info crit = 351.535278
R-squared = 0.65309422
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 0.9 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 9.4293e-07 (init = 0.3)
Result of fit 5:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 7
# data points = 79
# variables = 6
chi-square = 5612.92543
reduced chi-square = 76.8893895
Akaike info crit = 348.806979
Bayesian info crit = 363.023666
R-squared = 0.45138574
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
DR: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 0.30000000 (init = 0.3)
Result of fit 6:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 33
# data points = 79
# variables = 6
chi-square = 4077.91814
reduced chi-square = 55.8618923
Akaike info crit = 323.567628
Bayesian info crit = 337.784315
R-squared = 0.45327036
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.1 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 0.15260810 (init = 0.3)
Result of fit 7:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 49
# data points = 79
# variables = 6
chi-square = 2605.08961
reduced chi-square = 35.6861590
Akaike info crit = 288.166186
Bayesian info crit = 302.382873
R-squared = 0.51391474
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.2 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 0.90438060 (init = 1)
DR: 0.07226203 (init = 0.3)
Result of fit 8:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 45
# data points = 79
# variables = 6
chi-square = 1632.08535
reduced chi-square = 22.3573336
Akaike info crit = 251.225112
Bayesian info crit = 265.441800
R-squared = 0.59502628
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.3 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 0.00109133 (init = 0.3)
Result of fit 9:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 7
# data points = 79
# variables = 6
chi-square = 2625.23496
reduced chi-square = 35.9621228
Akaike info crit = 288.774748
Bayesian info crit = 302.991436
R-squared = 0.14529171
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
DR: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.4 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 0.30000000 (init = 0.3)
Result of fit 10:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 94
# data points = 79
# variables = 6
chi-square = 1125.86967
reduced chi-square = 15.4228721
Akaike info crit = 221.892193
Bayesian info crit = 236.108880
R-squared = 0.52964625
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.5 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 0.99556129 (init = 1)
DR: 4.2597e-08 (init = 0.3)
Result of fit 11:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 77
# data points = 79
# variables = 6
chi-square = 931.656975
reduced chi-square = 12.7624243
Akaike info crit = 206.933830
Bayesian info crit = 221.150518
R-squared = 0.49367226
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.6 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 0.90010005 (init = 1)
DR: 1.4090e-04 (init = 0.3)
Result of fit 12:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 30
# data points = 79
# variables = 6
chi-square = 679.778696
reduced chi-square = 9.31203694
Akaike info crit = 182.033236
Bayesian info crit = 196.249923
R-squared = 0.48692309
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
DR: at boundary
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.7 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 5.0854e-09 (init = 0.3)
Result of fit 13:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 44
# data points = 79
# variables = 6
chi-square = 1205.03922
reduced chi-square = 16.5073866
Akaike info crit = 227.260744
Bayesian info crit = 241.477431
R-squared = -0.25761835
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at boundary
DR: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.8 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 0.90000199 (init = 1)
DR: 0.30000000 (init = 0.3)
Result of fit 14:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 26
# data points = 79
# variables = 6
chi-square = 1174.66525
reduced chi-square = 16.0913048
Akaike info crit = 225.243960
Bayesian info crit = 239.460647
R-squared = -0.62183223
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
DR: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 1.9 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 0.30000000 (init = 0.3)
Result of fit 15:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 38
# data points = 79
# variables = 6
chi-square = 346.694258
reduced chi-square = 4.74923641
Akaike info crit = 128.840640
Bayesian info crit = 143.057327
R-squared = 0.38543152
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at initial value
[[Variables]]
spectrum_nb: 0 (fixed)
q: 2 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 1.00000000 (init = 1)
DR: 2.0083e-05 (init = 0.3)
Result of fit 16:
[[Model]]
(Model(irf_gate) <function convolve at 0x7f96d4295ca0> Model(sqwWaterTeixeira))
[[Fit Statistics]]
# fitting method = leastsq
# function evals = 66
# data points = 79
# variables = 6
chi-square = 671.788438
reduced chi-square = 9.20258134
Akaike info crit = 181.099153
Bayesian info crit = 195.315841
R-squared = -0.49568389
## Warning: uncertainties could not be estimated:
scale: at initial value
D: at initial value
resTime: at initial value
radius: at boundary
[[Variables]]
spectrum_nb: 0 (fixed)
q: 2.1 (fixed)
scale: 10.00000000 (init = 10)
center: 0.00000000 (init = 0)
D: 0.13000000 (init = 0.13)
resTime: 0.10000000 (init = 0.1)
radius: 0.90000101 (init = 1)
DR: 0.16526761 (init = 0.3)
Plot results using lmfit’s features
[18]:
for i in range(nb_q_values):
result_fit[i].plot();
Other option to plot experimental data, initial fitting model and fitted model for each spectrum using matplotlib.pyplot
[19]:
for indx in range(nb_q_values):
fig4 = plt.figure()
plt.plot(f_5A['x'][indx], f_5A['y'][indx], 'bo',label='exp')
plt.plot(f_5A['x'][indx], result_fit[indx].init_fit, 'k--',label='ini')
plt.plot(f_5A['x'][indx], result_fit[indx].best_fit, 'r-', label='fin')
plt.title(f"q={data_5A['q'][indx]:.2}")
plt.legend()
plt.grid()
[ ]: