How To Interpolate A 2D Curve In Python
I have a set of x & y coordinate which is a curve / shape, I want the smooth the curve / sharp and plot a graph. I tried different interpolation to smooth the curve / shape, Bu
Solution 1:
Because the interpolation is wanted for generic 2d curve i.e. (x, y)=f(s)
where s
is the coordinates along the curve, rather than y = f(x)
, the distance along the line s
have to be computed first. Then, the interpolation for each coordinates is performed relatively to s
. (for instance, in the circle case y = f(x)
have two solutions)
s
(or distance
in the code here) is calculated as the cumulative sum of the length of each segments between the given points.
import numpy as np
from scipy.interpolate import interp1d
import matplotlib.pyplot as plt
# Define some points:
points = np.array([[0, 1, 8, 2, 2],
[1, 0, 6, 7, 2]]).T # a (nbre_points x nbre_dim) array
# Linear length along the line:
distance = np.cumsum( np.sqrt(np.sum( np.diff(points, axis=0)**2, axis=1 )) )
distance = np.insert(distance, 0, 0)/distance[-1]
# Interpolation for different methods:
interpolations_methods = ['slinear', 'quadratic', 'cubic']
alpha = np.linspace(0, 1, 75)
interpolated_points = {}
for method in interpolations_methods:
interpolator = interp1d(distance, points, kind=method, axis=0)
interpolated_points[method] = interpolator(alpha)
# Graph:
plt.figure(figsize=(7,7))
for method_name, curve in interpolated_points.items():
plt.plot(*curve.T, '-', label=method_name);
plt.plot(*points.T, 'ok', label='original points');
plt.axis('equal'); plt.legend(); plt.xlabel('x'); plt.ylabel('y');
which gives:
Regarding the graphs, it seems you are looking for a smoothing method rather than an interpolation of the points. Here, is a similar approach use to fit a spline separately on each coordinates of the given curve (see Scipy UnivariateSpline):
import numpy as np
import matplotlib.pyplot as plt
from scipy.interpolate import UnivariateSpline
# Define some points:
theta = np.linspace(-3, 2, 40)
points = np.vstack( (np.cos(theta), np.sin(theta)) ).T
# add some noise:
points = points + 0.05*np.random.randn(*points.shape)
# Linear length along the line:
distance = np.cumsum( np.sqrt(np.sum( np.diff(points, axis=0)**2, axis=1 )) )
distance = np.insert(distance, 0, 0)/distance[-1]
# Build a list of the spline function, one for each dimension:
splines = [UnivariateSpline(distance, coords, k=3, s=.2) for coords in points.T]
# Computed the spline for the asked distances:
alpha = np.linspace(0, 1, 75)
points_fitted = np.vstack( spl(alpha) for spl in splines ).T
# Graph:
plt.plot(*points.T, 'ok', label='original points');
plt.plot(*points_fitted.T, '-r', label='fitted spline k=3, s=.2');
plt.axis('equal'); plt.legend(); plt.xlabel('x'); plt.ylabel('y');
which gives:
Post a Comment for "How To Interpolate A 2D Curve In Python"