0

im pretty new lerning how to use python and i have this problem. I need to plot some data from a csv file and fit a gaussian curve to it. But for some reason, the fit is just a straight line.

Here's my code

import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import scipy.optimize as opt
from scipy.optimize import curve_fit
data = pd.read_csv('DRXRed.csv',delimiter=",", names=['2T', 'I'])
plt.xlabel('2\u03B8[Grados]')
plt.ylabel('Intensidad[u.a]')
plt.title('Pico Máximo Difractograma Sr\u2082bCoO\u2086')
plt.grid(visible=True)
def Gauss(x, A, B):
    y = A*np.exp(-1*B*x**2)+2000
    return y
parameters, covariance = curve_fit(Gauss, data['2T'],data['I'])
fit_A = parameters[0]
fit_B = parameters[1]
fit_y = Gauss(data['2T'], fit_A, fit_B)
print(fit_A)
print(fit_B)
plt.plot(data['2T'], data['I'],color="r", label='data')
plt.plot(data['2T'], fit_y, '-', label='fit')
plt.savefig('Pico.png', dpi=1080)

And here's my function

enter image description here

It shows me this warning but i dont know what it means

/Library/Frameworks/Python.framework/Versions/3.8/lib/python3.8/site-packages/scipy/optimize/minpack.py:833: OptimizeWarning: Covariance of the parameters could not be estimated
  warnings.warn('Covariance of the parameters could not be estimated',
1.0
1.0

I would be very grateful for any help :)

Felipe Reyes
  • 31
  • 1
  • 2
  • Perhaps [this post](https://stackoverflow.com/q/50371428/2476977) addresses your concerns – Ben Grossmann Jan 26 '22 at 01:46
  • I think your principal problem is that you fixed 1) the bias in your gaussian. 2) the center. You fixed the center to 0. try using `data['2T'] -32` everywhere. This is a workaround to see if that's the problem, if you see some curve near gaussian fitted, then you will have to modify your gauss function to take at least a parameter for the center. `A*np.exp(-1*B*(x-C)**2)+2000` – Ulises Bussi Jan 26 '22 at 03:31

1 Answers1

0

After playing a while can conclude the problems are:

  1. you need to consider a center for x coordinates.
  2. you will have to put some initial guesses.

creating a toy data allows to play with it to get good results:


import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import scipy.optimize as opt
from scipy.optimize import curve_fit

# toy data
x = np.arange(28,36,0.01)
y = 5600 * np.exp(-2*(x-32)**2) + 1900 + 80*np.random.randn(len(x))
#plt.plot(x,y)


plt.xlabel('2\u03B8[Grados]')
plt.ylabel('Intensidad[u.a]')
plt.title('Pico Máximo Difractograma Sr\u2082bCoO\u2086')
#plt.grid(visible=True)

#acá agregué un parámetro C
def Gauss(x, A, B,C):
    y = A*np.exp(-1*B*(x-C)**2)+2000
    return y


#condiciones iniciales
#a0 es la amplitud, 
#b0 sería el ancho como desvío estandar, 
#c0 el centro en x

a0 = y.max()-y.min()

max_idx = np.argmax(y)
b0 = abs(max_idx - np.argmin((y-0.7*y.max())**2)) #i'm not sure this is a good guess but  it works

c0 = x[max_idx]

par0 = [a0,b0,c0]


parameters, covariance = curve_fit(Gauss, x,y,p0=par0)
#fit_A = parameters[0]
#fit_B = parameters[1]
fit_y = Gauss(x, *parameters)
#print(fit_A)
#print(fit_B)
plt.plot(x, y,color="r", label='data')
plt.plot(x,a0*np.exp(-b0*(x-c0)**2)+2000,color="b", label='initial_guess')

plt.plot(x, fit_y, '--k', label='fit')
plt.legend()

this get this results:

enter image description here

Ulises Bussi
  • 1,635
  • 1
  • 2
  • 14