Search code examples
pythonmatplotlibmachine-learningscipydata-science

The fitting curve does not match with experimental data. How can I match the curve fitting?


The red color indicates curve fitting and the magenta color indicates experimental dataenter image description here

I try to change the initial guessing parameters, but it does not work. Below is my code

x=file[0] # 1st column gives time
y=file[1]  # 2nd column gives intensity

#plotting time vs intensity

plt.xlabel('Delay (ps)')
plt.ylabel('Intnesity [arb.unit]')

plt.plot(x,y,'mo')

# curve fitting
# optimize import curve_fit

from scipy.optimize import curve_fit
def func(t, t_g, ):
    return 1+2*np.exp(-(t/t_g)**2)

y_fit=func(x,y)
rng = np.random.default_rng()
y_noise = 0.01 * rng.normal(size=x.size)
ydata = y_fit + y_noise
# plt.plot(x, ydata, 'b-', label='data')

popt, pcov = curve_fit(func, x, ydata, p0=0.09, absolute_sigma=True)
print(popt,'popt')
plt.plot(x, func(x, *popt), 'r-')
# print(popt,pcov)
perr = np.sqrt(np.diag(pcov))
print(perr,'std')
print(pcov,'pcov')

# plt.xlim(-0.2,0.2)
plt.show()

Solution

  • Give your model more degrees of freedom.

    import matplotlib.pyplot as plt
    import numpy as np
    from scipy.optimize import curve_fit
    import pandas as pd
    
    with open('pulseCheck Data 2023-01-10 11-47-12.txt') as f:
        for i, line in enumerate(f):
            if line.startswith('# ==='):
                break
        df = pd.read_csv(f, sep='\t', skiprows=2, names=('time', 'acf_data'))
    
    
    def func(t: np.ndarray, a: float, b: float, c: float, d: float) -> np.ndarray:
        return a + b*np.exp(-((t - c)/d)**2)
    
    
    popt, pcov = curve_fit(func, df.time, df.acf_data, p0=(0, 0.1, 0, 0.1))
    perr = np.sqrt(np.diag(pcov))
    print(popt, 'popt')
    print(perr,'std')
    print(pcov,'pcov')
    
    fig, ax = plt.subplots()
    
    ax.scatter(df.time, df.acf_data, label='data', marker='.', alpha=0.1, s=2)
    ax.plot(df.time, func(df.time, *popt), label='fit', color='r')
    ax.set_xlabel('Delay (ps)')
    ax.set_ylabel('Intensity')
    ax.legend()
    
    plt.show()
    
    [0.03509173 0.04534626 0.01325833 0.17030103] popt
    [4.69616443e-06 1.20114580e-05 3.53965703e-05 5.59280498e-05] std
    [[ 2.20539604e-11 -1.55945058e-11 -1.97261198e-19 -1.17132602e-10]
     [-1.55945058e-11  1.44275124e-10 -7.01612628e-18 -2.50790154e-10]
     [-1.97261198e-19 -7.01612628e-18  1.25291719e-09  3.35748882e-17]
     [-1.17132602e-10 -2.50790154e-10  3.35748882e-17  3.12794675e-09]] pcov
    

    graph