寻找曲线的最大值 scipy
Finding the maximum of a curve scipy
我已将曲线拟合到一组数据点。我想知道如何找到曲线的最大值点,然后我想注释该点(我不想使用数据中的最大 y 值来执行此操作)。我无法准确地编写我的代码,但这是我的代码的基本布局。
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))
还有办法找到峰宽吗?
我是否缺少可以执行此操作的简单内置函数?我可以微分函数并找到它为零的点吗?如果是这样怎么办?
如果您不介意使用 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]
找到最佳参数以最大化函数后,您可以使用 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()
当然,不是优化函数,我们可以只计算一堆 x 值并接近:
x = np.linspace(1, 5, 10000)
y = f(x, *popt)
imax = np.argmax(y)
print imax, x[imax] # 4996 2.99859985999
我已将曲线拟合到一组数据点。我想知道如何找到曲线的最大值点,然后我想注释该点(我不想使用数据中的最大 y 值来执行此操作)。我无法准确地编写我的代码,但这是我的代码的基本布局。
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))
还有办法找到峰宽吗?
我是否缺少可以执行此操作的简单内置函数?我可以微分函数并找到它为零的点吗?如果是这样怎么办?
如果您不介意使用 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]
找到最佳参数以最大化函数后,您可以使用 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()
当然,不是优化函数,我们可以只计算一堆 x 值并接近:
x = np.linspace(1, 5, 10000)
y = f(x, *popt)
imax = np.argmax(y)
print imax, x[imax] # 4996 2.99859985999