2016-05-12 13 views
3

Я пытаюсь установить экспоненциальный закон в свои данные. Мой пример (x,y) довольно сложный для объяснения, поэтому для общего понимания и воспроизводимости я скажу, что: обе переменные: float и continuous, 0<=x<=100 и 0<=y<=1.Неверный график с scipy.optimize.curve_fit (аналогично скользящей средней)

from scipy.optimize import curve_fit 
import numpy 
import matplotlib.pyplot as plt 

#ydata=[...] is my list with y values, which contains 0 values 
#xdata=[...] is my list with x values 

transf_y=[] 
for i in range(len(ydata)): 
    transf_y.append(ydata[i]+0.00001) #Adding something to avoid zero values 

x=numpy.array(xdata,dtype=float) 
y=numpy.array(transf_y,dtype=float) 

def func(x, a, c, d): 
    return a * numpy.exp(-c*x)+d 

popt, pcov = curve_fit(func, x, y,p0 = (1, 1e-6, 1)) 

print ("a = %s , c = %s, d = %s" % (popt[0], popt[1], popt[2])) 

xx = numpy.linspace(300, 6000, 1000) 
yy = func(xx, *popt) 

plt.plot(x,y,label='Original Data') 
plt.plot(xx, yy, label="Fitted Curve") 

plt.legend(loc='upper left') 
plt.show() 

Теперь моя встроенная кривая не выглядит похожей на экспоненциальную кривую. Скорее, это выглядит как скользящая средняя кривая, как если бы такая кривая была добавлена ​​как линия тренда в Excel. В чем может быть проблема? При необходимости я найду способ сделать доступные наборы данных, чтобы сделать пример воспроизводимым.

Это то, что я получаю из моего кода (я даже не знаю, почему я получаю три элемента в легенде пока только две построены, по крайней мере, по-видимому): enter image description here

ответ

4

enter image description here множество вещи:

  1. ваш сюжет изображает в исходных данных в два раза и без ощутимой установлены данные
  2. ваши данные, кажется, не заказывается, я полагаю, что именно поэтому вы получаете zickzack линии
  3. в вашем примере, ваш предсказывал участок будет находиться в диапазоне от 300 до 6000, тогда как ваших исходных данных 0 < = х < = 100

Именно в сторону, ваш код более или менее правильно и работает.

from scipy.optimize import curve_fit 
import numpy 
import matplotlib.pyplot as plt 

xdata=[100.0, 0.0, 90.0, 20.0, 80.0] #is my list with y values, which contains 0 values - edit, you need some raw data which you fit, I inserted some 
ydata=[0.001, 1.0, 0.02, 0.56, 0.03] #is my list with x values 

transf_y=[] 
for i in range(len(ydata)): 
    transf_y.append(ydata[i]+0.00001) #Adding something to avoid zero values 

x1=numpy.array(xdata,dtype=float) 
y1=numpy.array(transf_y,dtype=float) 

def func(x, a, c, d): 
    return a * numpy.exp(-c*x)+d 

popt, pcov = curve_fit(func, x1, y1,p0 = (1, 1e-6, 1)) 

print ("a = %s , c = %s, d = %s" % (popt[0], popt[1], popt[2])) 

#ok, sorting your data 
pairs = [] 
for i, j in zip(x1, y1): 
    pairs.append([i,j]) 

sortedList = sorted(pairs, key = lambda x:x[0]) 
sorted_x = numpy.array(sortedList)[:,0] 
sorted_y = numpy.array(sortedList)[:,1] 


#adjusting interval to the limits of your raw data 
xx = numpy.linspace(0, 100.0, 1000) 
yy = func(xx, *popt) 


#and everything looks fine 
plt.plot(sorted_x,sorted_y, 'o',label='Original Data') 
plt.plot(xx,yy,label='Fitted Data') 

plt.legend(loc='upper left') 
plt.show() 
+1

Таким образом, единственная большая проблема заключалась в том, что мои данные не были отсортированы. Я искренне думал, что это было сделано автоматически. Я был правдиво ошибался. – FaCoffee

+1

Да. И это только беспорядок на участках, фитинг в порядке. –