Non-linear curve fitting program in python

I would like to find and plot a function f representing a curve set at some number of given values ​​that I already know, x and y.

After doing some research, I started experimenting with scipy.optimize and curve_fit, but in the reference manual, I found that the program uses a function to fit the data and assumes ydata = f (xdata, * params) + eps.

So my question is this: what do I need to change in my code to use curve_fit or any other library to find the curve function using my presets? (note: I want to know this function, so I can integrate later for my project and bring in it). I know this will be a decaying exponential function, but I don't know the exact parameters. This is what I tried in my program:

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

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

    xdata = np.array([0.2, 0.5, 0.8, 1])
    ydata = np.array([6, 1, 0.5, 0.2])
    plt.plot(xdata, ydata, 'b-', label='data')
    popt, pcov = curve_fit(func, xdata, ydata)
    plt.plot(xdata, func(xdata, *popt), 'r-', label='fit')

    plt.xlabel('x')
    plt.ylabel('y')
    plt.legend()
    plt.show()

      

I am currently developing this project on a Raspberry Pi in case it changes anything. And I would love to use the least squares method because it is great and accurate, but any other method that works well is appreciated. Again, this is based on the scipy library reference manual. Also, I get the following graph which is not even a curve: graph and curve based on given points

[1]

+3


source to share


1 answer


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

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

#c is a constant so taking the derivative makes it go to zero
def deriv(x, a, b, c):
    return -a * b * np.exp(-b * x)

#Integrating gives you another c coefficient (offset) let call it c1 and set it equal to zero by default
def integ(x, a, b, c, c1 = 0):
    return -a/b * np.exp(-b * x) + c*x + c1

#There are only 4 (x,y) points here
xdata = np.array([0.2, 0.5, 0.8, 1])
ydata = np.array([6, 1, 0.5, 0.2])

#curve_fit already uses "non-linear least squares to fit a function, f, to data"
popt, pcov = curve_fit(func, xdata, ydata)
a,b,c = popt #these are the optimal parameters for fitting your 4 data points

#Now get more x values to plot the curve along so it looks like a curve
step = 0.01
fit_xs = np.arange(min(xdata),max(xdata),step)

#Plot the results
plt.plot(xdata, ydata, 'bx', label='data')
plt.plot(fit_xs, func(fit_xs,a,b,c), 'r-', label='fit')
plt.plot(fit_xs, deriv(fit_xs,a,b,c), 'g-', label='deriv')
plt.plot(fit_xs, integ(fit_xs,a,b,c), 'm-', label='integ')
plt.xlabel('x')
plt.ylabel('y')
plt.legend()
plt.show()

      



derivative and whole

+3


source







All Articles