Difference Between Scipy.interpolate.griddata And Scipy.interpolate.Rbf

- 1 answer

The Scipy functions griddata and Rbf can both be used to interpolate randomly scattered n-dimensional data. What is the difference between them? Is one of them superior in terms of accuracy or performance?

IMO, this is not a duplicate of this question, since I'm not asking how to perform the interpolation but instead what the technical difference between two specific methods is.



griddata is based on the Delaunay triangulation of the provided points. Data is then interpolated on each cell (triangle). For example, for a 2D function and a linear interpolation, the values inside the triangle are the plane going through the three adjacent points.

rbf works by assigning a radial function to each provided points. 'Radial' means that the function is only dependent on distance to the point. The value at any point is obtained by the sum of the weighted contribution of all the provided points. The method is applicable regardless of the dimension of the variable space, as soon as a distance function can be defined.

example rbf gauss

The graph is an example of a Gaussian based interpolation, with only two data points (black dots), in 1D. The two Gaussian (dashed line) are the basis function used. The interpolation function (solid red) is the sum of the these two curves. The weights for each points are internally determined by a system of linear equations, and the width of the Gaussian function is taken as the average distance between the points.

Here is the code to generate the graph:

import numpy as np
from matplotlib import pyplot as plt
%matplotlib inline

from scipy.interpolate import Rbf

x, y = [0, 1], [1, 2]

x_fine = np.linspace(-1, 2, 71)

interp_fun = Rbf(x, y, function='gaussian')

y_fine = interp_fun(x_fine)

for x0, weight in zip( x, interp_fun.nodes ):
    plt.plot(x_fine, weight*interp_fun._function(x_fine-x0), '--k', alpha=.7)

plt.plot(x_fine, y_fine, 'r', label='RFB Gaussian')
plt.plot(x, y, 'ok');
plt.xlabel('x'); plt.ylabel('y'); plt.legend();