用 Astropy 拟合数据(一)

用 Astropy 拟合数据(一)

astropy官网链接

步骤:获取数据 > 拟合

一:直线拟合

导入需要的模块

import numpy as np
import matplotlib.pyplot as plt
from astropy.modeling import models, fitting
from astroquery.vizier import Vizier
import scipy.optimize
# Make plots display in notebooks
%matplotlib inline

生成模拟数据(\(y = \frac{1}{2}x + 1\)),用高斯噪声产生误差

N = 100
x1 = np.linspace(0, 4, N) 
y1 = 0.5*x1 + 1
y1 += np.random.normal(0, 1, size=len(y1)) 
sigma = 1.
y1_err = np.ones(N)*sigma

画出生成的模拟数据

plt.errorbar(x1, y1, yerr=y1_err,fmt='k.')
plt.xlabel('$x_1$')
plt.ylabel('$y_1$')

image
拟合

model = models.Linear1D()
fitter = fitting.LinearLSQFitter()
best_fit = fitter(model, x1, y1, weights=1.0/y1_err**2)
print(best_fit)
Model: Linear1D
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Parameters:
    slope            intercept    
------------------- -----------------
0.42208417829280787 1.087132048161916

画拟合函数

plt.errorbar(x1,y1,y1_err,fmt='k.')
plt.plot(x1, best_fit(x1), color='g', linewidth=3)
plt.xlabel(r'x1')
plt.ylabel('y1')

image

二:多项式拟合

导入需要的模块

import numpy as np
import matplotlib.pyplot as plt
from astropy.modeling import models, fitting
from astroquery.vizier import Vizier
import scipy.optimize
# Make plots display in notebooks
%matplotlib inline

生成模拟数据 (\(y = x^3 - 3x^2 + 2x +2\))

N = 100
x2 = np.linspace(0, 3, N) 
y2 = x2**3 - 3*x2**2 + 2*x2 + 2
y2 += np.random.normal(0, 1, size=len(y1)) 
sigma = 1.
y2_err = np.ones(N)*sigma

画出生成的模拟数据

plt.errorbar(x2, y2, yerr=y2_err,fmt='k.')
plt.xlabel('$x_2$')
plt.ylabel('$y_2$')

image

拟合

model_poly = models.Polynomial1D(degree=3)
fitter_poly = fitting.LinearLSQFitter()
best_fit_poly = fitter_poly(model_poly, x2, y2, weights = 1.0/y2_err**2)
print(best_fit_poly)
Model: Polynomial1D
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Degree: 3
Parameters:
         c0               c1                 c2                 c3        
 ----------------- ---------------- ------------------- ------------------
 1.613139613446467 3.06121833229984 -3.7734605321689005 1.1552346626843524

拟合函数

plt.errorbar(x2,y2,y2_err,fmt='k.')
plt.plot(x2, best_fit_poly(x2), color='g', linewidth=3)
plt.xlabel(r'x2')
plt.ylabel('y2')

image

another fitter: SimplexLSQFitter

拟合

model_poly = models.Polynomial1D(degree=3)
fitter_poly_2 = fitting.SimplexLSQFitter()
best_fit_poly_2 = fitter_poly_2(model_poly, x2, y2, weights = 1.0/y2_err**2)
print(best_fit_poly_2)
Model: Polynomial1D
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Degree: 3
Parameters:
         c0                  c1                  c2                 c3        
 ------------------ ------------------- ------------------- ------------------
 2.8684868552438916 -1.2475744910421211 -1.3727224042018307 0.8091486564946109
WARNING: Model is linear in parameters; consider using linear fitting methods. [astropy.modeling.fitting]
WARNING: The fit may be unsuccessful; Maximum number of iterations reached. [astropy.modeling.optimizers]

拟合函数

plt.errorbar(x2,y2,y2_err,fmt='k.')
plt.plot(x2, best_fit_poly_2(x2), color='g', linewidth=3)
plt.xlabel(r'x2')
plt.ylabel('y2')

image

拟合的统计指标:Reduced Chi Square Value

def calc_reduced_chi_square(fit, x, y, yerr, N, n_free):
    '''
    fit (array) values for the fit
    x,y,yerr (arrays) data
    N total number of points
    n_free number of parameters we are fitting
    '''
    return 1.0/(N-n_free)*sum(((fit - y)/yerr)**2)

第一种拟合的 Reduced Chi Square Value

reduced_chi_squared = calc_reduced_chi_square(best_fit_poly(x2), x2, y2, y2_err, N, 4)
print('Reduced Chi Squared with LinearLSQFitter: {}'.format(reduced_chi_squared))

Reduced Chi Squared with LinearLSQFitter: 0.8378994724726152

第二种拟合的 Reduced Chi Square Value

reduced_chi_squared = calc_reduced_chi_square(best_fit_poly_2(x2), x2, y2, y2_err, N, 4)
print('Reduced Chi Squared with SimplexLSQFitter: {}'.format(reduced_chi_squared))

Reduced Chi Squared with SimplexLSQFitter: 1.3371509473069185

画图

plt.errorbar(x2, y2, yerr=y2_err,fmt='k.')
plt.plot(x2, best_fit_poly(x2), color='r', linewidth=3, label='LinearLSQFitter()')
plt.plot(x2, best_fit_poly_2(x2), color='g', linewidth=3, label='SimplexLSQFitter()')
plt.xlabel(r'x2')
plt.ylabel('y2')
plt.legend()

image

三:高斯拟合

生成模拟数据

mu, sigma, amplitude = 10.0, 5.0, 10.0
N2 = 100
x2 = np.linspace(-30, 50, N)
y2 = amplitude * np.exp(-(x2-mu)**2 / (2*sigma**2))
y2 = np.array([y_point + np.random.normal(0, 1) for y_point in y2])   #Another way to add random gaussian noise
sigma = 1
y2_err = np.ones(N)*sigma

画图

plt.errorbar(x2, y2, yerr=y2_err, fmt='k.')
plt.xlabel('$x_2$')
plt.ylabel('$y_2$')

image

拟合

model_gauss = models.Gaussian1D()
fitter_gauss = fitting.LevMarLSQFitter()
best_fit_gauss = fitter_gauss(model_gauss, x2, y2, weights=1/y2_err**2)

拟合结果

print(best_fit_gauss)
Model: Gaussian1D
Inputs: ('x',)
Outputs: ('y',)
Model set size: 1
Parameters:
     amplitude             mean              stddev     
 ------------------ ------------------ -----------------
 10.052672546272753 10.111106892698416 4.871675460663046

画拟合函数

plt.errorbar(x2, y2, yerr=y2_err, fmt='k.')
plt.plot(x2, best_fit_gauss(x2), 'r-', linewidth=3, label='astropy.modeling')
plt.xlabel('$x_2$')
plt.ylabel('$y_2$')
plt.legend()

image

posted @ 2021-04-09 22:48  zhaopw5  阅读(502)  评论(0编辑  收藏  举报