简体   繁体   English

基于点创建平滑线

[英]Creating a Smooth Line based on Points

I have the following dataset: 我有以下数据集:

x = [1, 6, 11, 21, 101]
y = [5, 4, 3, 2, 1]

and my goal is to create a smooth curve that looks like this: 我的目标是创建一个如下所示的平滑曲线: 在此输入图像描述

Is there a way to do it in Python? 有没有办法在Python中做到这一点?

I have attempted using the method shown in here , and here is the code: 我试过使用这里显示的方法,这里是代码:

from scipy.interpolate import spline

import matplotlib.pyplot as plt
import numpy as np

x = [1, 6, 11, 21, 101]
y = [5, 4, 3, 2, 1]

xnew = np.linspace(min(x), max(x), 100)

y_smooth = spline(x, y, xnew)

plt.plot(xnew, y_smooth)
plt.show()

but the output shows a weird line. 但输出显示一个奇怪的线。 在此输入图像描述

First, interpolate.spline() has been deprecated , so you should probably not use that. 首先, 不推荐使用 interpolate.spline() ,因此您可能不应该使用它。 Instead use interpolate.splrep() and interpolate.splev() . 而是使用interpolate.splrep()interpolate.splev() It's not a difficult conversion: 这不是一个困难的转换:

y_smooth = interpolate.spline(x, y, xnew)

becomes

tck = interpolate.splrep(x, y)
y_smooth = interpolate.splev(xnew, tck)

But, that's not really the issue here. 但是,这不是真正的问题。 By default, scipy tries to fit a polynomial of degree 3 to your data, which doesn't really fit your data. 默认情况下, scipy尝试将3度多项式拟合到您的数据中,这与您的数据不scipy But since there's so few points, it can fit your data fairly well even though it's a non-intuitive approximation. 但由于点数太少,它可以很好地适应您的数据,即使它是非直观的近似值。 You can set the degree of polynomial that it tries to fit with a k=... argument to splrep() . 可以设置它尝试与splrep()k=...参数拟合的多项式的次数。 But the same is true even of a polynomial of degree 2; 但即使是2阶多项式也是如此; it's trying to fit a parabola, and your data could possibly fit a parabola where there is a bow in the middle (which is what it does now, since the slope is so steep at the beginning and there's no datapoints in the middle). 它试图拟合抛物线,你的数据可能适合抛物线,中间有一个弓(这就是它现在所做的,因为斜率在开始时是如此陡峭,中间没有数据点)。

In your case, your data is much more accurately represented as an exponential, so it'd be best to fit an exponential. 在您的情况下,您的数据更准确地表示为指数,因此最好拟合指数。 I'd recommend using scipy.optimize.curve_fit() . 我建议使用scipy.optimize.curve_fit() It lets you specify your own fitting function which contains parameters and it'll fit the parameters for you: 它允许您指定自己的拟合函数,其中包含参数,它将适合您的参数:

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

x = [1, 6, 11, 21, 101]
y = [5, 4, 3, 2, 1]

xnew = np.linspace(min(x), max(x), 100)

def expfunc(x, a, b, c):
    return a * np.exp(-b * x) + c

popt, pcov = curve_fit(expfunc, x, y)
plt.plot(xnew, expfunc(xnew, *popt))
plt.show()

适合情节

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM