Skip to content Skip to sidebar Skip to footer

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? I have

Solution 1:

First, interpolate.spline() has been deprecated, so you should probably not use that. Instead use interpolate.splrep() and 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. 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(). But the same is true even of a polynomial of degree 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(). 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()

Fitted plot


Post a Comment for "Creating A Smooth Line Based On Points"