我有两个定义的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()
但是,我的结果如下:
答案 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')
会给你: