I am using the griddata function in scipy to interpolate 3 and 4 dimensional data. It works like a champ, except that it returns a bunch of NaNs because some of the points I need are outside the range of the input data. Given that N-d data only works with the "linear" mode interpolation anyway, it should be a snap to have griddata do an extrapolation instead of just returning NaN. Has anyone done this or found a workaround? To clarify: I have unstructured data, so I can't use any of the functions that require a regular grid. Thanks! Alex
2 Answers
One possibility to interpolate & extrapolate data with 3, 4 or actually any dimensions is with scipy.interpolate.Rbf
The get_data() function and plot_3d() function are attached to the end for convenience.
Example data
The example data looks like this (fourth dimension, w, is shown with a color). The data is irregularly spaced and not gridded.
x, y, z, w = get_data(N=200)
plot_3d(x, y, z, w)
Interpolation & extrapolation in 3d
First, let's setup new x and y coordinates. To make this more interesting, let's extrapolate to minus x and minus y direction. This forms the new x and y range of interest.
xs = np.linspace(-10, 20) # some extrapolation to negative numbers
ys = np.linspace(-10, 20) # some extrapolation to negative numbers
xnew, ynew = np.meshgrid(xs, ys)
xnew = xnew.flatten()
ynew = ynew.flatten()
Interpolation with scipy.interpolate.Rbf. Now,
from scipy.interpolate import Rbf
rbf3 = Rbf(x, y, z, function="multiquadric", smooth=5)
znew = rbf3(xnew, ynew)
plot_3d(xnew, ynew, znew)
- There can be as many variables/dimensions as you want. The first arguments (
x,y) are treated as coordinates for the nodes. The last argument before thefunctionargument are the "values" which are to be interpolated (now:z). - The
functionargument can be used to control how to values are interpolated. This will affect the results so play with it with your data.. - The
smoothparameter can be used to smooth some noise from the data. Ifsmoothis zero, the result is interpolating; it will go through all your data points. If it is positive value, the data is smoother. This will affect the results so play with it with your data.. - Below are the results and the extrapolation is of course badly off. This is just to demonstrate that extrapolation is possible. You might want to fine tune
functionandsmoothfor desired results. Usually, data should not be extrapolated "much" (like in this example)
Adding fourth dimension
It is also possible to interpolate & extrapolate to the fourth dimension. Here is how:
rbf4 = Rbf(x, y, z, w, function="thin_plate", smooth=5)
wnew = rbf4(xnew, ynew, znew)
plot_3d(xnew, ynew, znew, wnew)
- I created another
Rbfinstance for the fourth dimension and I used theznewcalculated with therbf3(interpolation in 3d). - I changed the
functionto"thin_plate"since it seemed visually to perform better with this dataset. - Here is how the results looks like:

Appendix: get_data and plot_3d
For testing purposes:
import numpy as np
def get_data():
np.random.seed(100)
N = 200
maxval = 20
x = np.random.random(N) * maxval
y = np.random.random(N) * maxval
z = x ** 2 + np.sqrt(y) * y - y ** 3 + np.random.random(N) + 18 * y ** 2 * 2
w = x ** 2 - np.log(y + (x * y) ** 2)
return x, y, z, w
def plot_3d(x, y, z, w=None, show=True):
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import axes3d
fig = plt.figure(figsize=(10, 6))
ax = axes3d.Axes3D(fig)
ax.scatter3D(x, y, z, c=w if not w is None else "b")
plt.show()
Not quite sure this will work for you and it is not available yet, but in the development version of numpy there is a 'pad' array function...
https://github.com/numpy/numpy/blob/master/numpy/lib/arraypad.py
One of the options is 'linear_ramp' which extrapolates (pads) outward starting at the edge value and linearly increase/decreases to a specified end value.
It is a pure python function so you could just copy it into your path and import (untested by me though)

