I have the below dataset:
import numpy as np
from scipy.optimize import curve_fit
import matplotlib.pyplot as plt
## Given datapoints
xdata = np.array([0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26])
ydata = np.array([1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0.99330715, 0.98201379, 0.95257413, 0.88079708, 0.73105858, 0.5])
## Plot the data
plt.plot(xdata, ydata)
plt.xlabel('x')
plt.ylabel('sigmoid(x)')
plt.xlim([-1,31])
plt.ylim(0, 1.05)
plt.show()
The above data looks as such:
A curve needs to be caliberated and extrapolated for y decreasing from 1 to 0 by using curve_fit in python.
I am trying to use sigmoid function provided that 'y' is given and 'x' need to be found.
The sigmoid function to fit 'x' is thus defined as such:
## Define sigmoid function to fit xdata
def sigmoid(y, x0, k):
x = x0 + ((1/k)*(np.log((1/y)-1)))
return x
## Initial guess
p0 = [np.median(xdata), # x0
0.1] # k
## Initialize curve fit
popt, pcov = curve_fit(sigmoid,
ydata,
xdata)
## Define values for y
y = np.arange(1,0,-0.001)
## Evaluate values for x
x = sigmoid(y, *popt)
## Plot tbe actual and fit data
plt.plot(xdata, ydata, 'o', label='data')
plt.plot(x,y, label='fit')
plt.xlim([-10,31])
plt.ylim(0, 1.05)
plt.legend(loc='best')
plt.show()
The fit data looks as such:
It is quite visible that the fit is not good.
Can somebody please let me know how I can fit a curve close to actual data?