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?




You might find
lmfituseful for this (disclaimer: I am a lead author), as it has sigmoidal step functions built in and can readily do fits and use those results to interpolate or extrapolate. It also gives more useful reports of results thancurve_fit, with variable parameters that have meaningful names and uncertainties and correlations correctly calculated, sorted and assigned.Your example might look like this:
which would print a report of
and make a plot like this: