Search code examples
python-3.xmatplotlibsmoothing

How to smooth a line in python3?


How to smooth this blue line, please?

import numpy as np
from matplotlib import pyplot as plt

a = [0.5365140382771445, 0.5214107372135204, 0.49844631119258076, 0.4681910992517213, 0.4310817214420628, 0.3882500155177606, 0.340292343154754, 0.2880252732908801]
b = [0.7416012836460293, 0.697385422521102, 0.6561831711375956, 0.6187959941327967, 0.585900754784896, 0.5586375446776617, 0.537388969490203, 0.5229339200070606]

time_fit = np.arange(len(b))
fitx = np.polyfit(time_fit, a, 2)
fity = np.polyfit(time_fit, b, 2)
x_fit = np.poly1d(fitx)
y_fit = np.poly1d(fity)

plt.figure(figsize=(8, 8))
plt.plot(x_fit, y_fit, c='red')
plt.plot(a, b, c = 'blue')
plt.show()

Do I fit it with the wrong polynomial?

enter image description here


Solution

  • So you are trying to fit a polynomial curve to your points. Let's break down how curve fitting for 2d points works. For simplicity, I've picked up 2nd order polynomial to fit the points. Also, I took the liberty of renaming your point names (a -> x and b ->y).

    np.polyfit returns polynomial coefficients against your specified order. You can make an actual polynomial class via applying np.poly1d to the returned coefficients. To plot the polynomial, we fit the x and get z. This (x,z) points are our fitted curve.

    import numpy as np
    from matplotlib import pyplot as plt
    
    
    x = [
        0.5365140382771445,
        0.5214107372135204,
        0.49844631119258076,
        0.4681910992517213,
        0.4310817214420628,
        0.3882500155177606,
        0.340292343154754,
        0.2880252732908801,
    ]
    y = [
        0.7416012836460293,
        0.697385422521102,
        0.6561831711375956,
        0.6187959941327967,
        0.585900754784896,
        0.5586375446776617,
        0.537388969490203,
        0.5229339200070606,
    ]
    
    # fitting x, y in a second order equation
    # this returns the coefficient of p_0*x^2 + p_1*x + p_n = 0
    # building the polynomial
    poly = np.poly1d(np.polyfit(x, y, 2))
    
    # getting the points for plotting polynomial
    z = poly(x)
    
    plt.figure(figsize=(8, 8))
    
    # scatter plotting the actual value
    plt.scatter(x, y, c="blue", marker="o", label="original points")
    
    # plotting the polynomial curve
    plt.plot(x, z, c="red", label="fitted curve (2nd order)")
    plt.legend()
    plt.show()
    

    This returns,

    enter image description here