2016-05-12 4 views
3

Ich versuche, ein Exponentialgesetz in meine Daten einzufügen. Meine (x,y) Probe ist ziemlich kompliziert zu erklären, so dass ich für das allgemeine Verständnis und die Reproduzierbarkeit sagen werde: Beide Variablen sind float und continuous, 0<=x<=100 und 0<=y<=1.Falscher Graph mit scipy.optimize.curve_fit (ähnlich dem gleitenden Durchschnitt)

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() 

Jetzt sieht meine angepasste Kurve nicht wie eine angepasste Exponentialkurve aus. Es sieht vielmehr wie eine Kurve mit gleitendem Durchschnitt aus, als ob diese Kurve als Trendlinie in Excel hinzugefügt wurde. Was könnte das Problem sein? Wenn nötig werde ich einen Weg finden, die Datensätze verfügbar zu machen, um das Beispiel reproduzierbar zu machen.

Dies ist, was ich aus meinem Code zu bekommen (ich weiß nicht einmal, warum ich in der Legende drei Elemente bin immer während nur zwei aufgetragen sind, zumindest scheinbar): enter image description here

Antwort

4

enter image description here Eine Vielzahl von Dinge:

  1. Ihr Grundstück ein Originaldaten zeigt zweimal und keine erkennbaren Einbaudaten
  2. Ihre Daten nicht bestellt zu werden scheint, gehe ich davon aus, weshalb Sie zickzack Linien erhalten
  3. in Ihrem Beispiel Ihr vorhergesagtes Grundstück zwischen 300 und 6000, während Ihren Rohdaten 0 < = x < = 100

Abgesehen davon, Ihr Code ist mehr oder weniger korrekt und Arbeiten im Bereich.

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

Das einzige große Problem war, dass meine Daten nicht sortiert wurden. Ich dachte wirklich, dass das automatisch gemacht wurde. Ich habe mich wirklich geirrt. – FaCoffee

+1

Ja. Und das vermasselt nur die Parzellen, die Anpassung ist in Ordnung. –

Verwandte Themen