Cara menggunakan INTERPOLATE pada Python
There are several general interpolation facilities available in SciPy, for data in 1, 2, and higher dimensions: Show
1-D interpolation (interp1d)#The
>>> from scipy.interpolate import interp1d >>> x = np.linspace(0, 10, num=11, endpoint=True) >>> y = np.cos(-x**2/9.0) >>> f = interp1d(x, y) >>> f2 = interp1d(x, y, kind='cubic') >>> xnew = np.linspace(0, 10, num=41, endpoint=True) >>> import matplotlib.pyplot as plt >>> plt.plot(x, y, 'o', xnew, f(xnew), '-', xnew, f2(xnew), '--') >>> plt.legend(['data', 'linear', 'cubic'], loc='best') >>> plt.show() Another set of interpolations in >>> from scipy.interpolate import interp1d >>> x = np.linspace(0, 10, num=11, endpoint=True) >>> y = np.cos(-x**2/9.0) >>> f1 = interp1d(x, y, kind='nearest') >>> f2 = interp1d(x, y, kind='previous') >>> f3 = interp1d(x, y, kind='next') >>> xnew = np.linspace(0, 10, num=1001, endpoint=True) >>> import matplotlib.pyplot as plt >>> plt.plot(x, y, 'o') >>> plt.plot(xnew, f1(xnew), '-', xnew, f2(xnew), '--', xnew, f3(xnew), ':') >>> plt.legend(['data', 'nearest', 'previous', 'next'], loc='best') >>> plt.show() Multivariate data interpolation (griddata)#Suppose you have multidimensional data, for instance, for an underlying function f(x, y) you only know the values at points (x[i], y[i]) that do not form a regular grid. Suppose we want to interpolate the 2-D function >>> def func(x, y): ... return x*(1-x)*np.cos(4*np.pi*x) * np.sin(4*np.pi*y**2)**2 on a grid in [0, 1]x[0, 1] >>> grid_x, grid_y = np.mgrid[0:1:100j, 0:1:200j] but we only know its values at 1000 data points: >>> rng = np.random.default_rng() >>> points = rng.random((1000, 2)) >>> values = func(points[:,0], points[:,1]) This can be done with
>>> from scipy.interpolate import griddata >>> grid_z0 = griddata(points, values, (grid_x, grid_y), method='nearest') >>> grid_z1 = griddata(points, values, (grid_x, grid_y), method='linear') >>> grid_z2 = griddata(points, values, (grid_x, grid_y), method='cubic') One can see that the exact result is reproduced by all of the methods to some degree, but for this smooth function the piecewise cubic interpolant gives the best results: >>> import matplotlib.pyplot as plt >>> plt.subplot(221) >>> plt.imshow(func(grid_x, grid_y).T, extent=(0,1,0,1), origin='lower') >>> plt.plot(points[:,0], points[:,1], 'k.', ms=1) >>> plt.title('Original') >>> plt.subplot(222) >>> plt.imshow(grid_z0.T, extent=(0,1,0,1), origin='lower') >>> plt.title('Nearest') >>> plt.subplot(223) >>> plt.imshow(grid_z1.T, extent=(0,1,0,1), origin='lower') >>> plt.title('Linear') >>> plt.subplot(224) >>> plt.imshow(grid_z2.T, extent=(0,1,0,1), origin='lower') >>> plt.title('Cubic') >>> plt.gcf().set_size_inches(6, 6) >>> plt.show() Multivariate data interpolation on a regular grid (RegularGridInterpolator)#Suppose you have n-dimensional data on a regular grid,
and you want to interpolate it. In such a case, >>> import matplotlib.pyplot as plt >>> from scipy.interpolate import RegularGridInterpolator Suppose we want to interpolate this 2-D function. >>> def F(u, v): ... return u * np.cos(u * v) + v * np.sin(u * v) Suppose we only know some data on a regular grid. >>> fit_points = [np.linspace(0, 3, 8), np.linspace(0, 3, 8)] >>> values = F(*np.meshgrid(*fit_points, indexing='ij')) Creating test points and true values for evaluations. >>> ut, vt = np.meshgrid(np.linspace(0, 3, 80), np.linspace(0, 3, 80), indexing='ij') >>> true_values = F(ut, vt) >>> test_points = np.array([ut.ravel(), vt.ravel()]).T We can creat interpolator and interpolate test points using each method. >>> interp = RegularGridInterpolator(fit_points, values) >>> fig, axes = plt.subplots(2, 3, figsize=(10, 6)) >>> axes = axes.ravel() >>> fig_index = 0 >>> for method in ['linear', 'nearest', 'slinear', 'cubic', 'quintic']: ... im = interp(test_points, method=method).reshape(80, 80) ... axes[fig_index].imshow(im) ... axes[fig_index].set_title(method) ... axes[fig_index].axis("off") ... fig_index += 1 >>> axes[fig_index].imshow(true_values) >>> axes[fig_index].set_title("True values") >>> fig.tight_layout() >>> fig.show() As expected, the higher degree spline interpolations are closest to the true values, though are more expensive to compute than with linear or nearest. The slinear interpolation also matches the linear interpolation. Spline interpolation#Spline interpolation in 1-D: Procedural (interpolate.splXXX)#Spline interpolation requires two
essential steps: (1) a spline representation of the curve is computed, and (2) the spline is evaluated at the desired points. In order to find the spline representation, there are two different ways to represent a curve and obtain (smoothing) spline coefficients: directly and parametrically. The direct method finds the spline representation of a curve in a 2-D plane using the function
For curves in N-D space the function The keyword argument, s , is used to specify the amount of smoothing to perform during the spline fit. The default value of \(s\) is \(s=m-\sqrt{2m}\) where \(m\) is the number of data-points being fit. Therefore, if no smoothing is desired a value of \(\mathbf{s}=0\) should be passed to the routines. Once the spline representation of the data has been determined,
functions are available for evaluating the spline ( >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy import interpolate Cubic-spline >>> x = np.arange(0, 2*np.pi+np.pi/4, 2*np.pi/8) >>> y = np.sin(x) >>> tck = interpolate.splrep(x, y, s=0) >>> xnew = np.arange(0, 2*np.pi, np.pi/50) >>> ynew = interpolate.splev(xnew, tck, der=0) >>> plt.figure() >>> plt.plot(x, y, 'x', xnew, ynew, xnew, np.sin(xnew), x, y, 'b') >>> plt.legend(['Linear', 'Cubic Spline', 'True']) >>> plt.axis([-0.05, 6.33, -1.05, 1.05]) >>> plt.title('Cubic-spline interpolation') >>> plt.show() Derivative of spline >>> yder = interpolate.splev(xnew, tck, der=1) >>> plt.figure() >>> plt.plot(xnew, yder, xnew, np.cos(xnew),'--') >>> plt.legend(['Cubic Spline', 'True']) >>> plt.axis([-0.05, 6.33, -1.05, 1.05]) >>> plt.title('Derivative estimation from spline') >>> plt.show() All derivatives of spline >>> yders = interpolate.spalde(xnew, tck) >>> plt.figure() >>> for i in range(len(yders[0])): ... plt.plot(xnew, [d[i] for d in yders], '--', label=f"{i} derivative") >>> plt.legend() >>> plt.axis([-0.05, 6.33, -1.05, 1.05]) >>> plt.title('All derivatives of a B-spline') >>> plt.show() Integral of spline >>> def integ(x, tck, constant=-1): ... x = np.atleast_1d(x) ... out = np.zeros(x.shape, dtype=x.dtype) ... for n in range(len(out)): ... out[n] = interpolate.splint(0, x[n], tck) ... out += constant ... return out >>> yint = integ(xnew, tck) >>> plt.figure() >>> plt.plot(xnew, yint, xnew, -np.cos(xnew), '--') >>> plt.legend(['Cubic Spline', 'True']) >>> plt.axis([-0.05, 6.33, -1.05, 1.05]) >>> plt.title('Integral estimation from spline') >>> plt.show() Roots of spline >>> interpolate.sproot(tck) array([3.1416]) # may vary Notice that >>> x = np.linspace(-np.pi/4, 2.*np.pi + np.pi/4, 21) >>> y = np.sin(x) >>> tck = interpolate.splrep(x, y, s=0) >>> interpolate.sproot(tck) array([0., 3.1416]) Parametric spline >>> t = np.arange(0, 1.1, .1) >>> x = np.sin(2*np.pi*t) >>> y = np.cos(2*np.pi*t) >>> tck, u = interpolate.splprep([x, y], s=0) >>> unew = np.arange(0, 1.01, 0.01) >>> out = interpolate.splev(unew, tck) >>> plt.figure() >>> plt.plot(x, y, 'x', out[0], out[1], np.sin(2*np.pi*unew), np.cos(2*np.pi*unew), x, y, 'b') >>> plt.legend(['Linear', 'Cubic Spline', 'True']) >>> plt.axis([-1.05, 1.05, -1.05, 1.05]) >>> plt.title('Spline of parametrically-defined curve') >>> plt.show() Spline interpolation in 1-d: Object-oriented (UnivariateSpline)#The spline-fitting capabilities described above are also
available via an objected-oriented interface. The 1-D splines are objects of the The UnivariateSpline class can also be used to smooth data by providing a non-zero value of the smoothing parameter s, with the same meaning as the s keyword of
the The >>> import numpy as np >>> import matplotlib.pyplot as plt >>> from scipy import interpolate InterpolatedUnivariateSpline >>> x = np.arange(0, 2*np.pi+np.pi/4, 2*np.pi/8) >>> y = np.sin(x) >>> s = interpolate.InterpolatedUnivariateSpline(x, y) >>> xnew = np.arange(0, 2*np.pi, np.pi/50) >>> ynew = s(xnew) >>> plt.figure() >>> plt.plot(x, y, 'x', xnew, ynew, xnew, np.sin(xnew), x, y, 'b') >>> plt.legend(['Linear', 'InterpolatedUnivariateSpline', 'True']) >>> plt.axis([-0.05, 6.33, -1.05, 1.05]) >>> plt.title('InterpolatedUnivariateSpline') >>> plt.show() LSQUnivarateSpline with non-uniform knots >>> t = [np.pi/2-.1, np.pi/2+.1, 3*np.pi/2-.1, 3*np.pi/2+.1] >>> s = interpolate.LSQUnivariateSpline(x, y, t, k=2) >>> ynew = s(xnew) >>> plt.figure() >>> plt.plot(x, y, 'x', xnew, ynew, xnew, np.sin(xnew), x, y, 'b') >>> plt.legend(['Linear', 'LSQUnivariateSpline', 'True']) >>> plt.axis([-0.05, 6.33, -1.05, 1.05]) >>> plt.title('Spline with Specified Interior Knots') >>> plt.show() 2-D spline representation: Procedural (bisplrep)#For (smooth) spline-fitting to a 2-D surface, the function
To evaluate
the 2-D spline and its partial derivatives (up to the order of the spline), the function It is important to note that 2-D interpolation should not be used to find the spline representation of images. The algorithm used is not
amenable to large numbers of input points. The signal-processing toolbox contains more appropriate algorithms for finding the spline representation of an image. The 2-D interpolation commands are intended for use when interpolating a 2-D function as shown in the example that follows. This example uses the >>> import numpy as np >>> from scipy import interpolate >>> import matplotlib.pyplot as plt Define function over a sparse 20x20 grid >>> x_edges, y_edges = np.mgrid[-1:1:21j, -1:1:21j] >>> x = x_edges[:-1, :-1] + np.diff(x_edges[:2, 0])[0] / 2. >>> y = y_edges[:-1, :-1] + np.diff(y_edges[0, :2])[0] / 2. >>> z = (x+y) * np.exp(-6.0*(x*x+y*y)) >>> plt.figure() >>> lims = dict(cmap='RdBu_r', vmin=-0.25, vmax=0.25) >>> plt.pcolormesh(x_edges, y_edges, z, shading='flat', **lims) >>> plt.colorbar() >>> plt.title("Sparsely sampled function.") >>> plt.show() Interpolate function over a new 70x70 grid >>> xnew_edges, ynew_edges = np.mgrid[-1:1:71j, -1:1:71j] >>> xnew = xnew_edges[:-1, :-1] + np.diff(xnew_edges[:2, 0])[0] / 2. >>> ynew = ynew_edges[:-1, :-1] + np.diff(ynew_edges[0, :2])[0] / 2. >>> tck = interpolate.bisplrep(x, y, z, s=0) >>> znew = interpolate.bisplev(xnew[:,0], ynew[0,:], tck) >>> plt.figure() >>> plt.pcolormesh(xnew_edges, ynew_edges, znew, shading='flat', **lims) >>> plt.colorbar() >>> plt.title("Interpolated function.") >>> plt.show() 2-D spline representation: Object-oriented (BivariateSpline)#The
Using radial basis functions for smoothing/interpolation#Radial basis functions can be used for smoothing/interpolating scattered data in N dimensions, but should be used with caution for extrapolation outside of the observed data range. 1-D Example#This example compares the usage of the >>> import numpy as np >>> from scipy.interpolate import Rbf, InterpolatedUnivariateSpline >>> import matplotlib.pyplot as plt >>> # setup data >>> x = np.linspace(0, 10, 9) >>> y = np.sin(x) >>> xi = np.linspace(0, 10, 101) >>> # use fitpack2 method >>> ius = InterpolatedUnivariateSpline(x, y) >>> yi = ius(xi) >>> plt.subplot(2, 1, 1) >>> plt.plot(x, y, 'bo') >>> plt.plot(xi, yi, 'g') >>> plt.plot(xi, np.sin(xi), 'r') >>> plt.title('Interpolation using univariate spline') >>> # use RBF method >>> rbf = Rbf(x, y) >>> fi = rbf(xi) >>> plt.subplot(2, 1, 2) >>> plt.plot(x, y, 'bo') >>> plt.plot(xi, fi, 'g') >>> plt.plot(xi, np.sin(xi), 'r') >>> plt.title('Interpolation using RBF - multiquadrics') >>> plt.show() 2-D Example#This example shows how to interpolate scattered 2-D data: >>> import numpy as np >>> from scipy.interpolate import Rbf >>> import matplotlib.pyplot as plt >>> from matplotlib import cm >>> # 2-d tests - setup scattered data >>> rng = np.random.default_rng() >>> x = rng.random(100)*4.0-2.0 >>> y = rng.random(100)*4.0-2.0 >>> z = x*np.exp(-x**2-y**2) >>> edges = np.linspace(-2.0, 2.0, 101) >>> centers = edges[:-1] + np.diff(edges[:2])[0] / 2. >>> XI, YI = np.meshgrid(centers, centers) >>> # use RBF >>> rbf = Rbf(x, y, z, epsilon=2) >>> ZI = rbf(XI, YI) >>> # plot the result >>> plt.subplot(1, 1, 1) >>> X_edges, Y_edges = np.meshgrid(edges, edges) >>> lims = dict(cmap='RdBu_r', vmin=-0.4, vmax=0.4) >>> plt.pcolormesh(X_edges, Y_edges, ZI, shading='flat', **lims) >>> plt.scatter(x, y, 100, z, edgecolor='w', lw=0.1, **lims) >>> plt.title('RBF interpolation - multiquadrics') >>> plt.xlim(-2, 2) >>> plt.ylim(-2, 2) >>> plt.colorbar() |