Как я могу поместить гауссовую кривую в python?
Мне присваивается массив, и когда я рисую его, я получаю гауссовскую форму с некоторым шумом. Я хочу соответствовать гауссову. Это то, что у меня уже есть, но когда я закладываю это, я не получаю гауссажа, вместо этого я просто получаю прямую линию. Я пробовал это много разных способов, и я просто не могу понять это.
random_sample=norm.rvs(h)
parameters = norm.fit(h)
fitted_pdf = norm.pdf(f, loc = parameters[0], scale = parameters[1])
normal_pdf = norm.pdf(f)
plt.plot(f,fitted_pdf,"green")
plt.plot(f, normal_pdf, "red")
plt.plot(f,h)
plt.show()
![click for image]()
Ответы
Ответ 1
Вы можете использовать fit
из scipy.stats.norm
следующим образом:
import numpy as np
from scipy.stats import norm
import matplotlib.pyplot as plt
data = np.random.normal(loc=5.0, scale=2.0, size=1000)
mean,std=norm.fit(data)
norm.fit
пытается соответствовать параметрам нормального распределения на основе данных. И действительно, в приведенном выше примере mean
составляет приблизительно 2 и std
составляет приблизительно 5.
Чтобы сделать это, вы можете сделать:
plt.hist(data, bins=30, normed=True)
xmin, xmax = plt.xlim()
x = np.linspace(xmin, xmax, 100)
y = norm.pdf(x, mean, std)
plt.plot(x, y)
plt.show()
![введите описание изображения здесь]()
Синие квадраты - это гистограмма ваших данных, а зеленая линия - гауссовская с установленными параметрами.
Ответ 2
Вы можете найти lmfit полезным для этого. Он имеет встроенные методы для гауссова фитинга и множество удобных опций для проблем с подгонкой. См
https://lmfit.github.io/lmfit-py/builtin_models.html#example-1-fit-peaked-data-to-gaussian-lorentzian-and-voigt-profiles
Ответ 3
Вы также можете поместить функцию Гаусса с помощью функции curve_fit из scipy.optimize(), где вы можете определить свою собственную настраиваемую функцию. Здесь я приведу пример гауссовой подгонки. Например, если у вас есть два массива x
и y
.
from scipy.optimize import curve_fit
from scipy import asarray as ar,exp
x = ar(range(10))
y = ar([0,1,2,3,4,5,4,3,2,1])
n = len(x) #the number of data
mean = sum(x*y)/n #note this correction
sigma = sum(y*(x-mean)**2)/n #note this correction
def gaus(x,a,x0,sigma):
return a*exp(-(x-x0)**2/(2*sigma**2))
popt,pcov = curve_fit(gaus,x,y,p0=[1,mean,sigma])
plt.plot(x,y,'b+:',label='data')
plt.plot(x,gaus(x,*popt),'ro:',label='fit')
plt.legend()
Функция curve_fit должна вызываться с тремя аргументами: функция, которую вы хотите поместить (gaus() в этом случае), значения независимой переменной (в нашем случае x) и значения переменной depenedent (в нашем случае y). Функция curve_fit funtion возвращает массив с оптимальными параметрами (в смысле наименьших квадратов) и второй массив, содержащий ковариацию оптимальных параметров (подробнее об этом позже).
Ниже приведен результат соответствия.
![введите описание изображения здесь]()
Ответ 4
Существует множество способов привязки gaussian-функции к набору данных. Я часто использую астропию при подгонке данных, поэтому я хотел добавить это в качестве дополнительного ответа.
Я использую некоторый набор данных, который должен имитировать гауссовский шум с некоторым шумом:
import numpy as np
from astropy import modeling
m = modeling.models.Gaussian1D(amplitude=10, mean=30, stddev=5)
x = np.linspace(0, 100, 2000)
data = m(x)
data = data + np.sqrt(data) * np.random.random(x.size) - 0.5
data -= data.min()
plt.plot(x, data)
![введите описание изображения здесь]()
Тогда установка на самом деле довольно проста, вы указываете модель, которую хотите поместить в данные и слесарь:
fitter = modeling.fitting.LevMarLSQFitter()
model = modeling.models.Gaussian1D() # depending on the data you need to give some initial values
fitted_model = fitter(model, x, data)
И построено:
plt.plot(x, data)
plt.plot(x, fitted_model(x))
![введите описание изображения здесь]()
Однако вы также можете использовать только Scipy, но вы должны сами определить функцию:
from scipy import optimize
def gaussian(x, amplitude, mean, stddev):
return amplitude * np.exp(-((x - mean) / 4 / stddev)**2)
popt, _ = optimize.curve_fit(gaussian, x, data)
Это возвращает оптимальные аргументы для соответствия, и вы можете построить его так:
plt.plot(x, data)
plt.plot(x, gaussian(x, *popt))
![введите описание изображения здесь]()