四参数曲线拟合pyqt实现
原公式
y=(a-d)/[1+(x/c)b]+d使用
from scipy.optimize import curve_fit
拟合自定义函数表述的公式,在拟合多项式时较为简便,公式中带有除法时拟合失败的情况较多
为此,将原
return (a-d)/[1+np.power(x/c, b)]+d
改为了line63:
return np.exp(np.log(e) - np.log(1 + np.power(x / c, b))) + a - e
其中,exp减少除法,用e代替a-d可避免log(0)的情形,因为curve_fit可以给定参数拟合范围,只要将e的范围限定为0到正无穷即可,line66指定了四参数的范围,前一个数组为四参数的下界,后一个数组表示四参数上界:
param_bounds = ([0, -np.inf, 0, 0], [np.inf, 0, np.inf, np.inf])
其余代码使用了PyQt5和matplotlib.pyplot结合,用于收集数据和展示,完整代码:
1 import matplotlib.pyplot as plt 2 # plt.rcParams['figure.figsize']=(5.0, 5.0) 3 from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg 4 5 import numpy as np 6 from scipy.optimize import curve_fit 7 import sys 8 from PyQt5.QtWidgets import QApplication, QWidget, QLabel, QHBoxLayout, QVBoxLayout, QTextEdit, QPushButton 9 from PyQt5.QtCore import Qt, pyqtSlot 10 import matplotlib 11 matplotlib.use('agg') 12 13 14 class WinForm(QWidget): 15 def __init__(self, parent=None): 16 super(WinForm, self).__init__(parent) 17 self.setWindowTitle("参数拟合") 18 self.resize(900, 500) 19 self.edit = QTextEdit() 20 self.edit.resize(200, 500) 21 self.label = QLabel() 22 self.label.setTextInteractionFlags(Qt.TextSelectableByMouse) 23 self.label.setStyleSheet("font-size:25px;") 24 self.widget_layout = QHBoxLayout() 25 26 layout = QHBoxLayout() 27 v_layout = QVBoxLayout() 28 button = QPushButton("提交") 29 button.clicked.connect(self.submit) 30 v_layout.addWidget(self.edit) 31 v_layout.addWidget(button) 32 33 layout.addLayout(v_layout) 34 layout.addLayout(self.widget_layout) 35 layout.addWidget(self.label) 36 self.setLayout(layout) 37 38 # y = np.array([0.01897993,0.020563813,0.020426801,0.020144805,0.019675034,0.019398058,0.018892107,0.018940092,0.018901446,0.019291514,0.019503548,0.019630093,0.019545104,0.01988369,0.019911492,0.019726401,0.020057849,0.019793866,0.019859317,0.019405032,0.019722957,0.019647644,0.020014258,0.019926352,0.020110741,0.019992224,0.020309811,0.019643045,0.019823269,0.019921443,0.020032414,0.019728777,0.020161777,0.019885736,0.019903189,0.02021257,0.020003425,0.019893611,0.020291727,0.020050692,0.020379189,0.020006046,0.019827,0.020088204,0.020474234,0.020361283,0.020112001,0.020347901,0.020032595,0.020078571,0.019900288,0.019825603,0.020045149,0.019977986,0.020025125,0.02025585,0.020385212,0.020129202,0.020278119,0.020173047,0.020057394,0.019834609,0.020222318,0.019899092,0.020024573,0.020322529,0.02029143,0.020291606,0.02050184,0.019912467,0.019805542,0.019988761,0.019981587,0.019948191,0.020190128,0.020263607,0.020464468,0.020299727,0.020210864,0.019736762,0.019942823,0.020027247,0.019332014,0.020040068,0.02010582,0.020134837,0.019988471,0.020209096,0.020021981,0.019698896,0.020136735,0.019984374,0.020327836,0.019427006,0.020031145,0.020306879,0.020188019,0.019909845,0.019966803,0.01948495,0.019935634,0.019766342,0.020186064,0.020088231,0.019970609,0.019971554,0.019922432,0.0198508,0.01976188,0.019573769,0.019483168,0.01935386,0.019568739,0.019738329,0.020175834,0.020017114,0.019436694,0.020042469,0.019916329,0.019792992,0.019395439,0.019472481,0.01955972,0.019869922,0.019658474,0.019410486,0.019163159,0.019771973,0.019708137,0.019109526,0.019054287,0.019573194,0.019803523,0.019997276,0.020148471,0.019584762,0.01935141,0.019802118,0.019489911,0.019333492,0.019448335,0.019294111,0.019443919,0.019444528,0.019589192,0.019978935,0.019768431,0.019589192,0.019321817,0.019417343,0.019444528,0.019308855,0.019804221,0.019505864,0.019335055,0.019807831,0.019247487,0.019587853,0.019730465,0.019399068,0.019422304,0.019370825,0.019647713,0.019486038,0.018035125,0.01958974,0.01962815,0.019714699,0.019470675,0.019189863,0.019678752,0.01960459,0.019496946,0.019621864,0.019540686,0.01943562,0.019575924,0.019829932,0.019651957,0.019374998,0.019333871,0.019307084,0.019347021,0.019662427,0.019473715,0.018959969,0.018925656,0.019409696,0.019473394,0.019072499,0.019307067,0.018759322,0.019381013,0.019670343,0.019328538,0.019498223,0.019606673,0.019596208,0.019251784,0.01929151,0.019305155,0.019116944,0.019335995,0.019405746,0.01957923,0.019368647,0.019193434,0.019668201,0.019099131,0.018878645,0.019378893,0.019340092,0.019488176,0.01911758,0.019406431,0.019607513,0.019332441,0.019611982,0.019169568,0.019146417,0.019404699,0.019461762,0.019001115,0.019396855,0.0192719,0.019173704,0.019387889,0.019353278,0.019237123,0.019034125,0.019072312,0.019169657,0.019033977,0.019361891,0.019025955,0.019229378,0.019136166,0.019151421,0.019253991,0.019271045,0.019370187,0.019291062,0.019344881,0.019291448,0.019237277,0.019358331,0.019421734,0.019367073,0.019139266,0.018870996,0.019062728,0.019180508,0.019350748,0.01925759,0.019413536,0.019222261,0.019711317,0.019328807,0.019189272,0.018973689,0.019227793,0.019228335,0.018883407,0.019281398,0.01931514,0.019107911,0.019346871,0.018992274,0.019202864,0.018796653,0.01859515,0.018849121,0.018717517,0.018918178,0.01882604,0.018978789,0.019249428,0.019031699,0.018593223,0.018960757,0.018913409,0.019183032,0.019153591,0.018815203,0.018964314,0.018934989,0.019469843,0.019144077,0.019023883,0.018681252,0.018850208,0.019112577,0.018492822,0.018833784,0.018867173,0.019450948,0.018869859,0.019117608,0.01917079,0.01872036,0.018626348,0.018989803,0.018804724,0.018639802,0.018704989,0.018856467,0.018655873,0.018879479,0.018810529,0.01874879,0.018619991,0.018896132,0.018960757,0.018473793,0.018502429,0.018857874,0.019229252,0.018938042,0.019031759,0.018677313,0.01903515,0.018551908,0.01885839,0.01874879,0.018942501,0.018866828,0.018852314,0.01879699,0.018719214,0.018779541,0.018872611,0.0183456,0.018977708,0.018746193,0.018733193,0.019082007,0.018966253,0.019117842,0.018728701,0.019012481,0.018928673,0.019048285,0.019005395,0.01912906,0.01880005,0.019126759,0.019042347,0.018823847,0.019082007,0.018757376,0.018975303,0.018758479,0.018979683,0.018935464,0.01883159,0.019044477,0.019021918,0.019234232,0.018729586,0.018950726,0.0172841,0.019101502,0.01909344,0.019028543,0.01922653,0.019025858,0.019186458,0.019246629,0.019004121,0.018862828,0.018682697,0.018959856,0.019369996,0.018949887,0.019339629,0.019023902,0.018725828,0.019270804,0.019230629,0.018983061,0.019027235,0.01899373,0.019195948,0.019245933,0.019242162,0.019037561,0.0192892,0.019144561,0.018883398,0.018954703,0.019055268,0.019329709,0.019311259,0.018945903,0.0189871,0.018936819,0.019315378,0.019534135,0.01912027,0.01924565,0.019178463,0.019500326,0.018254866,0.019242311,0.019450301,0.018936328,0.019037137,0.019574673,0.019603982,0.019561063,0.019292784,0.019575604,0.019410994,0.019849812,0.019720022,0.019908454,0.019547352,0.019948303,0.019953514,0.019805076,0.020033138,0.020280946,0.020063892,0.020160357,0.020087627,0.02021849,0.020326748,0.019993328,0.020366324,0.019964704,0.020496828,0.020558057,0.020313089,0.020986279,0.020979578,0.020778765,0.020926636,0.021053353,0.021144044,0.021258153,0.021482656,0.021741759,0.021332183,0.021305077,0.021825127,0.021716929,0.021845516,0.021770661,0.022283646,0.022538758,0.022646074,0.022963026,0.023024863,0.022871433,0.023117089,0.023293424,0.023396912,0.023141619,0.023607477,0.024469713,0.024073569,0.024709259,0.024259022,0.024845396,0.024742439,0.025334819,0.025486432,0.025126446,0.025677915,0.026567518,0.026486642,0.026726157,0.02720408,0.027093765,0.027366946,0.027712259,0.027852677,0.027565947,0.02814404,0.029218459,0.029583732,0.029698196,0.030325754,0.029761179,0.030112405,0.030381262,0.030683971,0.030865044,0.031258411,0.032991366,0.032940369,0.03338703,0.034081798,0.033709781,0.034072875,0.034119874,0.034381355,0.034701428,0.034834567,0.03664187,0.037324958,0.037007722,0.03780205,0.038066296,0.038454563,0.038413416,0.038914972,0.039345303,0.039791768,0.040879767,0.041752457,0.0418978,0.041943653,0.042863108,0.042446041,0.043309814,0.04358029,0.043961833,0.04399984,0.046450642,0.046427253,0.047006912,0.046970002,0.047259532,0.047879409,0.047929555,0.048658842,0.049341004,0.048912852,0.051013246,0.050940516,0.051441378,0.051891837,0.052236442,0.052759832,0.052879131,0.052949854,0.053147614,0.053153255,0.055482946,0.055376653,0.05580137,0.056058639,0.056041243,0.056775619,0.057010736,0.056872611,0.057307418,0.057708392,0.058599497,0.059080678,0.059355168,0.059259321,0.059717245,0.059775309,0.060084115,0.060186466,0.060467337,0.060473188,0.061328271,0.061873953,0.061921953,0.061685871,0.062233192,0.06207135,0.062050397,0.062224653,0.062131039,0.062900741,0.062804548,0.063379024,0.06362521,0.063392512,0.063498182,0.063025768,0.063636933,0.064207344,0.064017965,0.064284238,0.063889344,0.06441725,0.064408577,0.064720284,0.064636557,0.064583403,0.064571443,0.06461454,0.064995664,0.064965831,0.064618429,0.064911833,0.065186083,0.065115713,0.065109892,0.06547114,0.065170007,0.065186083,0.065289175,0.065377522,0.064732355,0.065378318,0.065557947,0.065880258,0.065707557,0.065271244,0.065568388,0.065476683,0.065323985,0.065880179,0.065694935,0.065983391,0.065767175,0.06545731,0.065904907,0.065765035,0.065967987,0.065945108,0.06415455,0.065764402,0.065783968,0.065820335,0.065767833,0.065611202,0.065919315,0.065639854,0.065550655,0.065875305,0.065826463,0.066306126,0.065853323,0.065693684,0.065609298,0.06595433,0.06648516,0.065705107,0.065929433,0.065963236,0.066539113,0.066288929,0.065636304,0.065968503,0.066031522,0.065643384,0.065673117,0.065855983,0.065792889,0.066090707,0.066018135,0.065939535,0.065610994,0.065921168,0.065988407,0.066042368,0.066451568,0.065738065,0.066106816,0.066135084,0.065930334,0.06607234,0.066057561,0.066266965,0.065915707,0.0660198,0.066533104,0.066406472,0.066470359,0.066414274,0.066170687,0.065939535,0.066137578,0.065829389,0.066277958,0.066074693,0.066271895,0.066035479,0.06587194,0.066123021,0.065994095,0.066268154,0.065998974,0.066102174,0.066427764,0.066226061,0.066080137,0.066095304,0.066018976,0.066164235,0.066350001,0.066323972,0.065902812,0.064822821,0.066164981,0.066469064,0.066065538,0.066587057,0.065713756,0.066205665,0.066872415,0.066373659,0.066234801,0.066262643,0.066452706,0.066310762,0.066330968,0.066094558,0.066622326,0.066738925,0.066524146,0.066295185,0.066071038,0.065804306,0.066536462,0.066145147,0.066199777,0.066619687,0.066610995,0.066415713,0.06650985,0.06652058]) 39 # x = np.arange(1,len(y)+1) 40 # self.draw(x, y) 41 42 def draw(self, x, y): 43 res = self.calc(x, y) 44 self.label.setText('A:%.9f\nB:%.9f\nC:%.9f\nD:%.9f' % (res[1], res[2], res[3], res[4])) 45 while self.widget_layout.count()>0: 46 item = self.widget_layout.itemAt(0) 47 self.widget_layout.removeItem(item) 48 if item.widget(): 49 item.widget().deleteLater() 50 self.widget_layout.addWidget(res[0]) 51 52 def submit(self): 53 my_str = self.edit.toPlainText().strip() 54 y = np.array(my_str.split("\n")) 55 y = y.astype(np.float64) 56 x = np.arange(1, len(y) + 1) 57 self.draw(x, y) 58 59 def func(self, x, a, b, c, e): 60 # a-d=e d=a-e 61 # return (a-d)/[1+np.power(x/c, b)]+d 62 # return a*x**3+b*x**2+c*x+d 63 return np.exp(np.log(e) - np.log(1 + np.power(x / c, b))) + a - e 64 65 def calc(self, x, y): 66 param_bounds = ([0, -np.inf, 0, 0], [np.inf, 0, np.inf, np.inf]) 67 popt, pcov = curve_fit(self.func, x, y, bounds=param_bounds) # 训练函数 68 a = popt[0] 69 b = popt[1] 70 c = popt[2] 71 e = popt[3] 72 d = a - e 73 74 plt.close('all') 75 yvals = self.func(x, a, b, c, e) 76 plot1 = plt.plot(x, y, '*', label='point') 77 plot2 = plt.plot(x, yvals, 'r', label='line') 78 # plt.xlabel('x axis') 79 # plt.ylabel('y axis') 80 plt.legend(loc=4) 81 # plt.show() 82 return FigureCanvasQTAgg(plt.gcf()), a, b, c, d 83 84 85 if __name__ == "__main__": 86 app = QApplication(sys.argv) 87 w = WinForm() 88 w.show() 89 app.exec_()
四参数指定范围会影响拟合目标,适用与line38注释中例子相似的s形曲线,数据量过低等情形也会导致拟合失败
本例首次使用pyqt,参考了较多网络文章不再逐一指出,在此对诸位的分享表示感谢,欢迎分享转发
浙公网安备 33010602011771号