2016-08-22 5 views
0

Ich habe die folgenden x, y Daten (in grün). Ich möchte eine Polynomfunktion erhalten, die zu meiner Kurve passt. Die Kurve, die in Python passt, sieht gut aus (blau). Wenn ich die Koeffizienten des Polynoms verwende und die Funktion selbst erstelle, liegen die Ergebnisse nicht auf der blauen Kurve. Für kleine Werte von X mag das noch passen, aber für große Werte ist es völlig falsch. Im Bild ist y für x = 15 und 2.5 dargestellt (große Punkte).Python-Polynom-Kurvenanpassung - Koeffizienten nicht richtig

enter image description here

Die Daten:

x, y 
0.5883596178 18562.5 
0.6656014904 20850 
0.7407008741 22700 
0.8310800498 24525 
0.9479506185 26370 
1.0768193651 27922 
1.1983161945 29070 
1.3837939534 30410 
1.6650549531 31800 
1.946640319  32740 
2.3811442965 33655 
2.9126326549 34290 
3.6970654824 34800 
4.2868951065 34987.5 
4.8297935972 35102 
5.7876198835 35175 
7.3463468386 35050 
8.9861037519 34725 
10.5490727095 34285 
13.2260016159 33450 
16.5822270413 32795 
20.5352502646 32472 
25.7462680049 32475 

Der Code:

data = plb.loadtxt('fig3_1_tiltingRL.dat') 

x = data[:,0] 
y= data[:,1] 
#plt.xscale('log')#plt.set_xscale('log') 
coefs = poly.polyfit(x, y, 10) 
ffit = poly.polyval(x, coefs) 
plt.plot(x, ffit) 
plt.plot(x, y, 'o') 
print(coefs) 
xPoints =15. 
yPt = (-6.98662492e+03 * xPoints**0 + 6.57987934e+04 * xPoints**1 -\ 
     4.65689536e+04 * xPoints**2 + 1.85406629e+04 * xPoints**3 -\ 
     4.49987278e+03 * xPoints**4 + 6.92952944e+02 * xPoints**5 -\ 
     6.87501257e+01 * xPoints**6 + 4.35851202e+00 * xPoints**7 -\ 
     1.69771617e-01 * xPoints**8 + 3.68535224e-03 * xPoints**9 -\ 
     3.39940049e-05 * xPoints**10) 
print(yPt) 
plt.plot(xPoints, yPt , 'or',label="test" ,markersize=18, color='black') 
plt.show() 
+0

Bitte senden Sie uns eine kurze, aber in sich geschlossene '.py' Quelldatei: http://sscce.org/ – pts

+0

Es ist irgendwie verdächtig, dass die geraden Koeffizienten alle negativ und die ungeraden sind sind alle positiv. Was war die exakte Ausgabe von 'print (coefs)'? –

Antwort

0

Meiner Meinung nach ist die Art und Weise Sie die poyval verwenden sieht nicht richtig zu mir. Versuchen Sie, Ihre X-Achse mit numpy.linspace zu generieren und wenden Sie dann die polyval darauf an. Etwas wie der Code unten.

import numpy as np 
import matplotlib.pyplot as plt 


data = np.loadtxt('fig3_1_tiltingRL.dat') 

x = data[:,0] 
y= data[:,1] 
#plt.xscale('log')#plt.set_xscale('log') 
coefs = np.polyfit(x, y, 10) 
ffit = np.polyval(coefs, x) 

new_x = np.linspace(0,26) 
new_ffit = np.polyval(coefs, new_x) 

plt.plot(x, y, 'o', label="Raw") 
plt.plot(x, ffit,'x',label="Fit to Raw") 
plt.plot(new_x, new_ffit,label="Fit to LinSpace") 

# This is ugly. I'd use list comprehension here! 
arr = np.linspace(0,26,20) 
new_y = [] 
for xi in arr: 
    total = 0 
    for i,v in enumerate(coefs[::-1]): 
     total += v*xi**i 
    new_y.append(total) 


plt.plot(arr, new_y, '*', label="Polynomial") 

plt.legend(loc=2) 
plt.show() 

enter image description here

Wie Sie sehen können, gibt es einen Buckel, die nicht in Ihrem Plot erscheint ...

0

scheint Ihr Algorithmus funktioniert gut werden. Sie sollten nur statt:

coefs = poly.polyfit(x, y, 10) 
ffit = poly.polyval(x, coefs) 

dieses:

coefs = poly.polyfit(x, y, 10) # fit data to the polynomial 
new_x = np.linspace(0, 30, 50) # new x values to evaluate 
ffit = poly.polyval(new_x, coefs) # fitted polynomial evaluated with new data 

Somit ist die Funktion poly.polyval prüft alle Punkte des new_x anstelle der x Koordinaten, die Sie bereits kennen.

0

Vielen Dank für die Beantwortung meiner Frage.

Die Lösung von silgon und RicLeal funktioniert.

Am Ende, da ich mehrere Kurven hatte, habe ich die von RicLeal gegebene Lösung angewendet.

Meine Daten wurden auf der X-Achse protokolliert. Ich habe gerade den von RicLeal vorgegebenen Code geändert und bin mit dem Ergebnis zufrieden.

enter image description here

x = data[:,0] 
y= data[:,1] 
plt.xscale('log')#plt.set_xscale('log') 
logx=np.log10(x) 
coefs = np.polyfit(logx, y, 10) 
ffit = np.polyval(coefs, logx) 
print (coefs) 


logxmin=math.log10(0.5883596178) 
logxmax=math.log10(26.) 

new_x = np.logspace(logxmin, logxmax,50) 
lognew_x=np.log10(new_x) 
new_ffit = np.polyval(coefs, lognew_x) 
plt.semilogx(x, y, 'o', label="Raw") 
plt.semilogx(x, ffit,'x',label="Fit to Raw") 
plt.semilogx(new_x, new_ffit,label="Fit to LogSpace") 
print(lognew_x, new_ffit) 
# This is ugly. I'd use list comprehension here! 
arr = np.logspace(logxmin, logxmax,50) 
arrlog= np.log10(arr) 
new_y = [] 
for xi in arrlog: 
    total = 0 
    for i,v in enumerate(coefs[::-1]): 
     #print (v) 
     total += v*xi**i 
    new_y.append(total) 


    plt.semilogx(arr, new_y, '*', label="Polynomial") 

coeffs= [6.85869364,  -92.86678553, 343.39375022,   -555.52532934, 434.18179364, 
    -152.82724751,  9.71300951, 21.68653301, -35.62838377, 28.3985976, 
     27.04762122] 
new_testy = [] 
for xi in arrlog: 
total = 0 
    for i,v in enumerate(coeffs[::-1]): 
     #print (v) 
     total += v*xi**i 
    new_testy.append(total)   
plt.semilogx(arr, new_testy, 'o', label="Polynomial")   
plt.legend(loc=2) 
plt.show() 
Verwandte Themen