I want to fit a monotonically increasing smooth spline function for a dataset
Code:
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
x = [0., 0.75, 1.8, 2.25, 3.75, 4.5, 6.45, 6.75, 7.5, 8.325, 10.875, 11.25, 12.525, 12.75, 15., 20.85, 21.]
y = [2.83811035, 2.81541896, 3.14311655, 3.22373554, 3.43033456, 3.50433385, 3.66794514, 3.462296, 3.59480959,
3.56250726, 3.6209845, 3.63034523, 3.68238915, 3.69096892, 3.75560395, 3.83545191, 3.90419498]
plt.plot(x, y, '*')
f = interp1d(x, y, kind='cubic')
yinp = f(x)
plt.plot(x, yinp)
plt.show()
f = interp1d(x, y, kind='cubic')
yinp = f(x)
plt.plot(x, yinp)
plt.show()
The current fit looks like the above. I would like to know how to fit a monotonically increasing spline function.
I found an example in r posted here https://stackoverflow.com/questions/25447999/how-to-make-monotonic-increasing-smooth-spline-with-smooth-spline-function. I am not sure what's the appropriate function in the scipy library.
Suggestions will be really helpful.
Crossposted: https://stackoverflow.com/questions/73605390/fitting-a-monotonously-increasing-spline-function-using-scipy
EDIT: I'm looking for something like the below (ref.)
EDIT 2: I could get the coeffs and knots but I am not sure how to use the coefficients and manually generate the function of the spline curve. Could someone please add a bit more detail to this?
For example, when we have 4 data points x = [0., 0.75, 1.8, 2.25] y = [2.83811035, 2.81541896, 3.14311655, 3.22373554]
I would like to print the piecewise polynomial function to understand how the spline function looks like.
EDIT 3: The solution posted below works great.
I am trying to print the spline for each segment
f0 = lambda x: p.c[0, i] * (x - p.x[i]) ** 3 + p.c[1, i] * (x - p.x[i]) ** 2 + p.c[2, i] * (x - p.x[i]) + p.c[3, i]
f0 = lambda x: [p.c[:, i] * (x - p.x[i]) ** (3 - i) for i in range(k + 1)]
print(f0)
This prints <function fit_spline1.. at 0x0000028697B94F70>
Instead, I would like to see the cubic polynomial. Could someone please suggest how to print this out?