【问题标题】:Plotting graph using scipy.optimize.curve_fit使用 scipy.optimize.curve_fit 绘制图形
【发布时间】:2018-12-16 05:42:23
【问题描述】:

我无法理解optimize.curve_fit 函数。我的拟合函数是幂律。但我不确切知道 plot 命令中的第二个值应该是什么?首先我们必须调用函数ff(L,v),它会返回拟合线,但我们没有调用这个函数。这个命令是如何工作的我想知道。

x=Ls
y=Tc
#fitting function
def ff(L,v):
    return L**(-1/v)
pfit,perr=optimize.curve_fit(ff,x,y)
plt.plot(x,...)

【问题讨论】:

    标签: python matplotlib scipy


    【解决方案1】:

    plot 命令绘制 x 与 y 值,因此您必须根据定义的函数 ff 计算相应的 y 值。由于pfit 以数组形式返回,因此在调用拟合函数ff 时必须解压缩这些值。如果你知道你有两个系数,你当然可以像v, k = pfit 那样简单地提取它们,然后用ff(x, v, k) 计算y 值。但是,如果您稍后将 fit 函数更改为 L**(-1/v) * k + a 怎么办?然后你将不得不重写你的代码。一种更简单的方法是让 Python 使用 *pfit 解压缩系数:

    from scipy.optimize import curve_fit
    from matplotlib import pyplot as plt
    import numpy as np
    
    #define some sample data
    x = np.arange(1, 6)
    y = np.asarray([100, 37, 18, 3, 1])
    
    #fitting function with more than one parameter to fit
    def ff(L, v, k):
        return L**(-1/v) * k
    
    pfit, perr = curve_fit(ff,x,y)
    print(pfit)
    
    #plot original data
    plt.plot(x, y, "ro", label = "data")
    #calculate y-values
    y_fit = ff(x, *pfit)
    #plot fitted curve
    plt.plot(x, y_fit, "b", label = "fit")
    plt.legend()
    plt.show()
    

    这当然不够令人印象深刻,拟合曲线看起来一点也不平滑:

    为了克服这个问题,我们可能希望创建一个分辨率更高的 x 值范围并绘制这个范围,而不是原始 x 值数据:

    x_fit = np.linspace(np.min(x), np.max(x), 1000)
    plt.plot(x_fit, ff(x_fit, *pfit), "b", label = "fit")
    

    现在好多了:

    【讨论】:

    • 我们是否可以更改比例,使曲线与 y 轴接触,以便我可以轻松读取 y 轴上的值?我可以将这个负斜率转换为正斜率吗?
    • 负斜率在您的原始数据中,而不是在拟合函数本身中。您可以将拟合函数中的 v 符号反转为 L**(1/v),但随后拟合函数将简单地返回 -v。第一个问题与原来的问题相差甚远,如果您不熟悉使用plt.ylim() 重新缩放图形或使用plt.axhlines() 绘制水平线,您应该问另一个问题。
    • 好的,我发布一个新问题。还有一件事我想知道,在拟合函数时,您提到了另一个不在幂律中的常数。为什么我们要添加这个常数?
    • 仅出于教育目的,以便您更容易理解,为什么我们不简单地从 pfit 中提取 v 并将其手动输入 fit 函数。 (对于我的随机数据集,拟合函数收敛的问题更少,但这是一个完全不同的问题。)
    猜你喜欢
    • 2015-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多