Interpolating a curve on a plot

Viewed 70

I am hoping to plot a smooth curve given a number of points (1-d x and y array). I thought I could use the package make_interp_spline but it looks like the x array needs to be sorted evenly... How do I use make_interp_spline without sorting the x dimension of the array or work around the error?

from scipy.interpolate import make_interp_spline
import numpy as np
#from scipy import stats
import matplotlib.pyplot as plt


x = np.array([-31,-30,-30,-32,-36,-39])
y = np.array([60,62,64,65,64,64])

#plot non-interpolated curve 
plt.plot(x,y);

#x = x.reshape(6)
#y = y.reshape(6)

# wher the error occurs about the 1d sorted array
X_Y_Spline = make_interp_spline(x, y)

X_ = np.linspace(x.min(), x.max(), 500)
Y_ = X_Y_Spline(X_)

plt.plot(X_, Y_);


---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
/tmp/ipykernel_2083810/662623888.py in <module>
      7 #y = y.reshape(6)
      8 
----> 9 X_Y_Spline = make_interp_spline(x, y)
     10 
     11 X_ = np.linspace(x.min(), x.max(), 500)

~/miniconda3/envs/py3_std_maps/lib/python3.9/site-packages/scipy/interpolate/_bsplines.py in make_interp_spline(x, y, k, t, bc_type, axis, check_finite)
    784 
    785     if x.ndim != 1 or np.any(x[1:] < x[:-1]):
--> 786         raise ValueError("Expect x to be a 1-D sorted array_like.")
    787     if np.any(x[1:] == x[:-1]):
    788         raise ValueError("Expect x to not have duplicates")

ValueError: Expect x to be a 1-D sorted array_like.
3 Answers

Better to use "interp1d" from "scipy.interpolate".

from scipy.interpolate import interp1d
import numpy as np
import matplotlib.pyplot as plt


x = np.array([-31,-30,-30,-32,-36,-39])
y = np.array([60,62,64,65,64,64])


X_Y_Spline = interp1d(x, y)
X_ = np.linspace(x.min(), x.max(), 500)
Y_ = X_Y_Spline(X_)

plt.plot(X_, Y_)

Workaround is to make a monotonically increasing n dimension where x and y arrays can follow.

See:

from scipy.interpolate import interp1d
import numpy as np
import matplotlib.pyplot as plt


x = np.array([-31,-30,-30,-32,-36,-39])
n = np.arange(x.shape[0]) 
y = np.array([60,62,64,65,64,64])


x_spline = interp1d(n, x,kind='cubic')

n_ = np.linspace(n.min(), n.max(), 500)
y_spline = interp1d(n, y,kind='cubic')

x_ = x_spline(n_)
y_ = y_spline(n_)



plt.plot(x_, y_)

plt.plot(x,y);

enter image description here

Just np.argsort the x array and use the result to sort both x and y simultaneously.

Related