Python Scipy指数曲线拟合

时间:2014-07-17 10:24:16

标签: python numpy scipy curve-fitting exponential

我有两个定义的numpy数组fx和fy,并希望使用带有a和t作为拟合参数的scipy.optimize.curve_fitting,使用简单的代码将指数曲线拟合到数据集。

import numpy as np
import pylab as plt
import scipy.optimize as op

k=1.38e-23
h=6.63e-34
c=3e8

fx=np.array([ 552.715,  553.21 ,  553.705,  554.2  ,  554.695,  555.19 ,
555.685,  556.18 ,  556.675,  557.17 ,  557.665,  558.16 ,
558.655,  559.15 ,  559.645,  560.14 ,  560.635,  561.13 ,
561.625,  562.12 ,  562.615,  563.11 ,  563.605,  564.1  ,
564.595,  565.09 ,  565.585,  566.08 ,  566.575,  567.07 ,
567.565,  568.06 ,  568.555,  569.05 ,  569.545,  570.04 ,
570.535,  571.03 ,  571.525,  572.02 ,  572.515,  573.01 ,
573.505,  574.   ,  574.495,  574.99 ,  575.485,  575.98 ,
576.475,  576.97 ,  577.465,  577.96 ,  578.455,  578.95 ,
579.445,  579.94 ,  580.435,  580.93 ,  581.425,  581.92 ,
582.415,  582.91 ,  583.405,  583.9  ,  584.395,  584.89 ,
585.385,  585.88 ,  586.375,  586.87 ,  587.365,  587.86 ,
588.355,  588.85 ,  589.345,  589.84 ,  590.335,  590.83 ,
591.325,  591.82 ,  592.315,  592.81 ,  593.305,  593.8  ,
594.295,  594.79 ,  595.285,  595.78 ,  596.275,  596.77 ,
597.265,  597.76 ,  598.255,  598.75 ,  599.245,  599.74 ,
600.235,  600.73 ,  601.225,  601.72 ,  602.215,  602.71 ,
603.205,  603.7  ,  604.195,  604.69 ,  605.185,  605.68 ,
606.175,  606.67 ,  607.165,  607.66 ,  608.155,  608.65 ,
609.145,  609.64 ,  610.135,  610.63 ,  611.125,  611.62 ,
612.115,  612.61 ,  613.105,  613.6  ,  614.095,  614.59 ,
615.085,  615.58 ,  616.075,  616.57 ,  617.065,  617.56 ,
618.055,  618.55 ,  619.045,  619.54 ,  620.035,  620.53 ,
621.025,  621.52 ,  622.015,  622.51 ,  623.005,  623.5  ,
623.995,  624.49 ,  624.985,  625.48 ,  625.975])

fy=np.array([  1.00594059e+01,   1.09504950e+01,   1.18712871e+01,
 1.30198020e+01,   1.39504950e+01,   1.50990099e+01,
 1.70792079e+01,   1.88118812e+01,   2.09306931e+01,
 2.28712871e+01,   2.52772277e+01,   2.78118812e+01,
 3.05742574e+01,   3.37227723e+01,   3.65841584e+01,
 4.01584158e+01,   4.36732673e+01,   4.74653465e+01,
 5.15940594e+01,   5.58613861e+01,   6.06435644e+01,
 6.50990099e+01,   7.01881188e+01,   7.54554455e+01,
 8.09801980e+01,   8.70198020e+01,   9.32079208e+01,
 9.99603960e+01,   1.06990099e+02,   1.14306931e+02,
 1.22148515e+02,   1.30485149e+02,   1.39049505e+02,
 1.48158416e+02,   1.57960396e+02,   1.68198020e+02,
 1.79326733e+02,   1.91000000e+02,   2.03138614e+02,
 2.16356436e+02,   2.30168317e+02,   2.44356436e+02,
 2.59603960e+02,   2.75643564e+02,   2.92425743e+02,
 3.10000000e+02,   3.28594059e+02,   3.48267327e+02,
 3.69227723e+02,   3.91257426e+02,   4.14742574e+02,
 4.39752475e+02,   4.66069307e+02,   4.93603960e+02,
 5.23871287e+02,   5.55257426e+02,   5.89168317e+02,
 6.24910891e+02,   6.63168317e+02,   7.04009901e+02,
 7.47643564e+02,   7.93504950e+02,   8.42445545e+02,
 8.95079208e+02,   9.50564356e+02,   1.00921782e+03,
 1.07177228e+03,   1.13699010e+03,   1.20611881e+03,
 1.27934653e+03,   1.35602970e+03,   1.43814851e+03,
 1.52452475e+03,   1.61438614e+03,   1.71103960e+03,
 1.81260396e+03,   1.91811881e+03,   2.03032673e+03,
 2.14822772e+03,   2.27108911e+03,   2.40198020e+03,
 2.53915842e+03,   2.68294059e+03,   2.83670297e+03,
 2.99874257e+03,   3.16921782e+03,   3.35154455e+03,
 3.54392079e+03,   3.74728713e+03,   3.96532673e+03,
 4.19456436e+03,   4.43693069e+03,   4.69555446e+03,
 4.96582178e+03,   5.24895050e+03,   5.55423762e+03,
 5.87050495e+03,   6.20618812e+03,   6.56147525e+03,
 6.93150495e+03,   7.31978218e+03,   7.72735644e+03,
 8.15521782e+03,   8.60201980e+03,   9.06632673e+03,
 9.54961386e+03,   1.00612376e+04,   1.06043069e+04,
 1.11605941e+04,   1.17525149e+04,   1.23515941e+04,
 1.29770891e+04,   1.36441485e+04,   1.43482376e+04,
 1.50911386e+04,   1.58885248e+04,   1.67236436e+04,
 1.76022871e+04,   1.85360297e+04,   1.95256139e+04,
 2.05648416e+04,   2.16838515e+04,   2.28497129e+04,
 2.40916634e+04,   2.54179307e+04,   2.68289109e+04,
 2.83307129e+04,   2.99250693e+04,   3.16013168e+04,
 3.34018218e+04,   3.53154455e+04,   3.73571584e+04,
 3.94992673e+04,   4.17868713e+04,   4.41894950e+04,
 4.67588416e+04,   4.94524257e+04,   5.22460198e+04,
 5.52046634e+04,   5.83112178e+04,   6.15341584e+04,
 6.49220693e+04,   6.84331089e+04,   7.20734356e+04,
 7.58653465e+04,   7.97503465e+04,   8.37502178e+04,
 8.79790000e+04,   9.23597030e+04])

def func(fx,a,t):
    return a*np.exp(-h*c/(fx*1e-9*kb/t))

norm_x=fx.min() #normalizing to avoid infinitely big values
norm_y=fy.max()
fx2=fx-norm_x+1
fy2=fy/norm_y

popt,pcov=op.curve_fit(func,fx2,fy2,p0=(1,1),maxfev=6000)

plt.plot(fx,fy)
plt.plot(fx,norm_y*func(fx2, *popt),'o')
plt.show()

但是,我的结果如下: IMG

1 个答案:

答案 0 :(得分:4)

你可能陷入了一个数值误差问题,因为计算曲线拟合算法中的误差的函数正在考虑大值的差异。

您可以将数据标准化,如:

norm_x = fx.min()
norm_y = fy.max()
fx2 = fx - norm_x + 1
fy2 = fy/norm_y

popt, pcov = op.curve_fit(func, fx2, fy2, p0=(1,1,1), maxfev=6000)

plt.plot(fx, fy, 'x', label='data')
plt.plot(fx, norm_y*func(fx2, *popt), 'o', mfc='none', label='curve-fit')
plt.legend(loc='upper left')

会给你:

enter image description here