2016-08-22 5 views
0

У меня есть следующие данные x, y (зеленым). Я хотел бы получить полиномиальную функцию, которая соответствует моей кривой. Кривая, которая установлена ​​внутри python, выглядит нормально (синим цветом). Когда я использую коэффициенты многочлена, и сам я построю функцию, результаты не находятся на синей кривой. При малых значениях X это может по-прежнему соответствовать, но для больших значений совершенно неверно. На изображении показаны y для x = 15 и 2.5 (большие точки).python polyomial curve fit - коэффициенты не правы

enter image description here

Данные:

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 

Код:

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

Пожалуйста, пост короткий, но автономный '.py' исходный файл: http://sscce.org/ – pts

+0

Это своего рода подозрительными, что даже коэффициенты отрицательны и нечетные все положительные. Каков был точный вывод 'print (coefs)'? –

ответ

0

На мой взгляд, то, как вы используете poyval не смотрит прямо на меня. Попробуйте создать ось X с помощью numpy.linspace, а затем нанесите на нее polyval. Что-то вроде кода ниже.

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

Как вы можете видеть, что есть горб, который не появляется в вашем сюжете ...

0

Ваш алгоритм, кажется, работает хорошо. Вы должны просто вместо:

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

это:

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 

Таким образом, функция poly.polyval будет оценивать все точки new_x вместо x координаты, которые вы уже знаете.

0

Спасибо, что ответили на мой вопрос.

Оба решения, предоставляемые Silgon и RicLeal работают.

В конце концов, поскольку у меня было несколько кривых, я применил решение, данное RicLeal.

Мои данные были зарегистрированы на оси х. Я только что изменил код, данный RicLeal, и я доволен результатом.

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() 
Смежные вопросы