我有多组四个数据点,我想为每一组在每个点之间的双对数图上创建一条线性趋势线(四个点意味着总共三条趋势线)。我使用scipy.optimize
中的curve_fit
来实现这一点。它适用于我所有的集合,除了一个集合:
大多数情况下,这与最初的猜测(p0
)有关,但在尝试了不同的猜测后,我仍然最终得到了这个。我在文献中看到,对于类似的值,这些图看起来很好,所以我一定错过了一些东西。
我在这里错过了什么,使它工作?我唯一能想到的是,猜测还是有问题的。我有一个测试代码下面复制粘贴。
代码:
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
import numpy as np
# Two lists with the information for the line
list_x = [3.139, 2.53, 0.821, 0.27]
list_y = [35.56, 26.82, 10.42, 4.66]
def func_exp(x, a, b):
return (a * x)**b
# Points
point1_x = list_x[0]
point1_y = list_y[0]
point2_x = list_x[1]
point2_y = list_y[1]
point3_x = list_x[2]
point3_y = list_y[2]
point4_x = list_x[3]
point4_y = list_y[3]
# Lines between points
p0_12 = (point1_x, point2_x)
formula_12, pcov_12 = curve_fit(func_exp, [point1_x, point1_y], [point2_x, point2_y], maxfev=10000, p0=p0_12)
p0_23 = (point2_x, point3_x)
formula_23, pcov_23 = curve_fit(func_exp, [point2_x, point2_y], [point3_x, point3_y], maxfev=10000, p0=p0_23)
p0_34 = (point3_x, point4_x)
formula_34, pcov_34 = curve_fit(func_exp, [point3_x, point3_y], [point4_x, point4_y], maxfev=10000, p0=p0_34)
# Create plot
plot_x_12 = np.linspace(point1_x, point2_x, 1000)
plot_y_12 = (formula_12[0] * plot_x_12)**formula_12[1]
plot_x_23 = np.linspace(point2_x, point3_x, 1000)
plot_y_23 = (formula_23[0] * plot_x_23)**formula_23[1]
plot_x_34 = np.linspace(point3_x, point4_x, 1000)
plot_y_34 = (formula_34[0] * plot_x_34)**formula_34[1]
fig, ax1 = plt.subplots(1, 1, figsize=(10, 5))
ax1.scatter(list_x, list_y, color='black')
ax1.plot(plot_x_12, plot_y_12)
ax1.plot(plot_x_23, plot_y_23)
ax1.plot(plot_x_34, plot_y_34)
ax1.set_xscale('log', base=10)
ax1.set_yscale('log', base=10)
1条答案
按热度按时间55ooxyrt1#
对于您的问题,我认为最好检查一次曲线拟合的输出与实际y值。根据你目前的配方,它们根本不匹配:
错误发生在curve_fit的函数调用上。第二个参数应该是x而不是第一个点等等.
因此,如果你使用下面的公式,你会得到一个看起来更清晰的图:
剧情: