Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

interpolate 3D volume with numpy and or scipy

I am extremely frustrated because after several hours I can't seem to be able to do a seemingly easy 3D interpolation in python. In Matlab all I had to do was

Vi = interp3(x,y,z,V,xi,yi,zi) 

What is the exact equivalent of this using scipy's ndimage.map_coordinate or other numpy methods?

Thanks

like image 664
user1301295 Avatar asked Feb 17 '14 17:02

user1301295


People also ask

What is Scipy interpolate in Python?

Interpolation is a technique of constructing data points between given data points. The scipy. interpolate is a module in Python SciPy consisting of classes, spline functions, and univariate and multivariate interpolation classes. Interpolation is done in many ways some of them are : 1-D Interpolation.

How does Scipy interpolation work?

The interp1d class in the scipy. interpolate is a convenient method to create a function based on fixed data points, which can be evaluated anywhere within the domain defined by the given data using linear interpolation. By using the above data, let us create a interpolate function and draw a new interpolated graph.

What does Scipy interpolate interp2d return?

Interpolate over a 2-D grid. x, y and z are arrays of values used to approximate some function f: z = f(x, y) which returns a scalar value z. This class returns a function whose call method uses spline interpolation to find the value of new points.


2 Answers

In scipy 0.14 or later, there is a new function scipy.interpolate.RegularGridInterpolator which closely resembles interp3.

The MATLAB command Vi = interp3(x,y,z,V,xi,yi,zi) would translate to something like:

from numpy import array from scipy.interpolate import RegularGridInterpolator as rgi my_interpolating_function = rgi((x,y,z), V) Vi = my_interpolating_function(array([xi,yi,zi]).T) 

Here is a full example demonstrating both; it will help you understand the exact differences...

MATLAB CODE:

x = linspace(1,4,11); y = linspace(4,7,22); z = linspace(7,9,33); V = zeros(22,11,33); for i=1:11     for j=1:22         for k=1:33             V(j,i,k) = 100*x(i) + 10*y(j) + z(k);         end     end end xq = [2,3]; yq = [6,5]; zq = [8,7]; Vi = interp3(x,y,z,V,xq,yq,zq); 

The result is Vi=[268 357] which is indeed the value at those two points (2,6,8) and (3,5,7).

SCIPY CODE:

from scipy.interpolate import RegularGridInterpolator from numpy import linspace, zeros, array x = linspace(1,4,11) y = linspace(4,7,22) z = linspace(7,9,33) V = zeros((11,22,33)) for i in range(11):     for j in range(22):         for k in range(33):             V[i,j,k] = 100*x[i] + 10*y[j] + z[k] fn = RegularGridInterpolator((x,y,z), V) pts = array([[2,6,8],[3,5,7]]) print(fn(pts)) 

Again it's [268,357]. So you see some slight differences: Scipy uses x,y,z index order while MATLAB uses y,x,z (strangely); In Scipy you define a function in a separate step and when you call it, the coordinates are grouped like (x1,y1,z1),(x2,y2,z2),... while matlab uses (x1,x2,...),(y1,y2,...),(z1,z2,...).

Other than that, the two are similar and equally easy to use.

like image 80
Steve Byrnes Avatar answered Sep 28 '22 00:09

Steve Byrnes


The exact equivalent to MATLAB's interp3 would be using scipy's interpn for one-off interpolation:

import numpy as np from scipy.interpolate import interpn  Vi = interpn((x,y,z), V, np.array([xi,yi,zi]).T) 

The default method for both MATLAB and scipy is linear interpolation, and this can be changed with the method argument. Note that only linear and nearest-neighbor interpolation is supported by interpn for 3 dimensions and above, unlike MATLAB which supports cubic and spline interpolation as well.

When making multiple interpolation calls on the same grid it is preferable to use the interpolation object RegularGridInterpolator, as in the accepted answer above. interpn uses RegularGridInterpolator internally.

like image 31
buzjwa Avatar answered Sep 28 '22 00:09

buzjwa