2015-04-29 93 views
4

我已經擬合了一組數據點的曲線。我想知道如何找到我的曲線的最大點,然後我想註釋這一點(我不想用我的數據中最大的y值來做到這一點)。我不能完全寫我的代碼,但這是我的代碼的基本佈局。查找曲線scipy的最大值

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

x = [1,2,3,4,5] 
y = [1,4,16,4,1] 

def f(x, p1, p2, p3): 
    return p3*(p1/((x-p2)**2 + (p1/2)**2)) 

p0 = (8, 16, 0.1) # guess perameters 
plt.plot(x,y,"ro") 
popt, pcov = curve_fit(f, x, y, p0) 
plt.plot(x, f(x, *popt)) 

還有沒有辦法找到峯寬?

我錯過了一個簡單的內置函數可以做到這一點嗎?我可以區分這個函數並找出它的零點嗎?如果是這樣如何?

+0

你試過'最大(Y )'或'y.max()'如果'y'是一個numpy數組? –

+0

它是一個數組,但我被要求找到曲線的最大值而不是數組中的最大數據點。 – skitt1z1

+0

這與編程無關。這是純粹的數學。要查找函數的最大值,需要計算其導數 –

回答

3

後你適合找最大化你的函數的最佳參數,你可以找到使用minimize_scalar(或scipy.optimize的其他方法)的峯值。

請注意,在下面,我移動了x[2]=3.2,以便曲線的峯值不落在數據點上,我們可以確定我們找到的是曲線的峯值,而不是數據。

import numpy as np 
import matplotlib.pyplot as plt 
from scipy.optimize import curve_fit, minimize_scalar 

x = [1,2,3.2,4,5] 
y = [1,4,16,4,1] 

def f(x, p1, p2, p3): 
    return p3*(p1/((x-p2)**2 + (p1/2)**2)) 

p0 = (8, 16, 0.1) # guess perameters 
plt.plot(x,y,"ro") 
popt, pcov = curve_fit(f, x, y, p0) 

# find the peak 
fm = lambda x: -f(x, *popt) 
r = minimize_scalar(fm, bounds=(1, 5)) 
print "maximum:", r["x"], f(r["x"], *popt) #maximum: 2.99846874275 18.3928199902 

x_curve = np.linspace(1, 5, 100) 
plt.plot(x_curve, f(x_curve, *popt)) 
plt.plot(r['x'], f(r['x'], *popt), 'ko') 
plt.show() 

enter image description here

當然,而不是優化的功能,我們可以只計算它的一堆x值和親近:

x = np.linspace(1, 5, 10000) 
y = f(x, *popt) 
imax = np.argmax(y) 
print imax, x[imax]  # 4996 2.99859985999 
+0

這正是我想要做的。謝謝! – skitt1z1

3

如果您不介意使用sympy,那很簡單。假設你發佈的代碼已經運行:

import sympy 

sym_x = sympy.symbols('x', real=True) 
sym_f = f(sym_x, *popt) 
sym_df = sym_f.diff() 
solns = sympy.solve(sym_df) # returns [3.0] 
+0

啊......那個工作很好,謝謝!有沒有類似的方式你可能知道使用scipy? – skitt1z1