GRID_INTERP

This function performs interpolation on a 2D rectilinear grid using either linear or nearest-neighbor rules. Grid coordinates for each axis define sample locations, and the function estimates values at requested query points.

For a query point (x, y) between surrounding grid nodes, linear interpolation computes a weighted combination of neighboring grid values, while nearest chooses the closest grid-supported value.

Excel Usage

=GRID_INTERP(points_x, points_y, values, xi, grid_interp_method, bounds_error, fill_value)
  • points_x (list[list], required): 1D array of x-coordinates of the grid points
  • points_y (list[list], required): 1D array of y-coordinates of the grid points
  • values (list[list], required): 2D array of data values on the grid
  • xi (list[list], required): Points at which to interpolate data (n_points, 2)
  • grid_interp_method (str, optional, default: “linear”): Interpolation method
  • bounds_error (bool, optional, default: true): If True, raise error for out-of-bounds points
  • fill_value (float, optional, default: null): Value for out-of-bounds points when bounds_error is False

Returns (list[list]): A 2D list of interpolated values, or an error message (str) if invalid.

Example 1: Linear interpolation at grid center

Inputs:

points_x points_y values xi
0 1 0 1 0 1 0.5 0.5
1 2

Excel formula:

=GRID_INTERP({0,1}, {0,1}, {0,1;1,2}, {0.5,0.5})

Expected output:

1

Example 2: Nearest-neighbor on 3x2 grid

Inputs:

points_x points_y values xi grid_interp_method
0 1 2 0 1 1 2 0.4 0.6 nearest
3 4
5 6

Excel formula:

=GRID_INTERP({0,1,2}, {0,1}, {1,2;3,4;5,6}, {0.4,0.6}, "nearest")

Expected output:

2

Example 3: Linear interpolation at multiple query points

Inputs:

points_x points_y values xi
0 1 0 1 0 1 0 0
2 3 1 1
0.5 0.5

Excel formula:

=GRID_INTERP({0,1}, {0,1}, {0,1;2,3}, {0,0;1,1;0.5,0.5})

Expected output:

Result
0
3
1.5
Example 4: Out-of-bounds query with custom fill value

Inputs:

points_x points_y values xi bounds_error fill_value
0 1 0 1 1 2 0.5 0.5 false -999
3 4 1.5 1.5

Excel formula:

=GRID_INTERP({0,1}, {0,1}, {1,2;3,4}, {0.5,0.5;1.5,1.5}, FALSE, -999)

Expected output:

Result
2.5
-999

Python Code

import math
import numpy as np
from scipy.interpolate import RegularGridInterpolator as scipy_RegularGridInterpolator

def grid_interp(points_x, points_y, values, xi, grid_interp_method='linear', bounds_error=True, fill_value=None):
    """
    Interpolator on a regular grid in 2D.

    See: https://docs.scipy.org/doc/scipy/reference/generated/scipy.interpolate.RegularGridInterpolator.html

    This example function is provided as-is without any representation of accuracy.

    Args:
        points_x (list[list]): 1D array of x-coordinates of the grid points
        points_y (list[list]): 1D array of y-coordinates of the grid points
        values (list[list]): 2D array of data values on the grid
        xi (list[list]): Points at which to interpolate data (n_points, 2)
        grid_interp_method (str, optional): Interpolation method Valid options: Linear, Nearest. Default is 'linear'.
        bounds_error (bool, optional): If True, raise error for out-of-bounds points Default is True.
        fill_value (float, optional): Value for out-of-bounds points when bounds_error is False Default is None.

    Returns:
        list[list]: A 2D list of interpolated values, or an error message (str) if invalid.
    """
    try:
      def to2d(x):
        return [[x]] if not isinstance(x, list) else x

      def flatten(arr):
        return [item for sublist in arr for item in sublist]

      # Normalize 2D list inputs
      points_x = to2d(points_x)
      points_y = to2d(points_y)
      values = to2d(values)
      xi = to2d(xi)

      # Validate grid_interp_method parameter
      valid_methods = ["linear", "nearest"]
      if not isinstance(grid_interp_method, str):
        return "Error: Invalid input: grid_interp_method must be a string."
      if grid_interp_method not in valid_methods:
        return f"Error: Invalid input: grid_interp_method must be one of {valid_methods}."

      # Validate bounds_error parameter
      if not isinstance(bounds_error, bool):
        return "Error: Invalid input: bounds_error must be a boolean."

      # Validate fill_value parameter
      if fill_value is not None:
        try:
          fill_value = float(fill_value)
          if math.isnan(fill_value):
            # NaN is allowed as fill_value
            pass
          elif math.isinf(fill_value):
            return "Error: Invalid input: fill_value must be finite or NaN."
        except (TypeError, ValueError):
          return "Error: Invalid input: fill_value must be a number or None."
      else:
        fill_value = float("nan")

      try:
        # Flatten points_x and points_y
        points_x_flat = flatten(points_x)
        points_y_flat = flatten(points_y)

        # Validate points are numeric
        for i, val in enumerate(points_x_flat):
          if not isinstance(val, (int, float)):
            return f"Error: Invalid input: points_x[{i}] must be numeric."
          if math.isnan(val) or math.isinf(val):
            return f"Error: Invalid input: points_x[{i}] must be finite."

        for i, val in enumerate(points_y_flat):
          if not isinstance(val, (int, float)):
            return f"Error: Invalid input: points_y[{i}] must be numeric."
          if math.isnan(val) or math.isinf(val):
            return f"Error: Invalid input: points_y[{i}] must be finite."

        # Convert values to numpy array
        values_arr = np.array(values, dtype=float)

        # Validate values dimensions
        if values_arr.ndim != 2:
          return "Error: Invalid input: values must be a 2D array."

        if values_arr.shape[0] != len(points_x_flat):
          return f"Error: Invalid input: values must have shape ({len(points_x_flat)}, {len(points_y_flat)})."

        if values_arr.shape[1] != len(points_y_flat):
          return f"Error: Invalid input: values must have shape ({len(points_x_flat)}, {len(points_y_flat)})."

        # Convert xi to numpy array
        xi_arr = np.array(xi, dtype=float)

        # Validate xi dimensions
        if xi_arr.ndim != 2:
          return "Error: Invalid input: xi must be a 2D array."

        if xi_arr.shape[1] != 2:
          return "Error: Invalid input: xi must have shape (n_points, 2)."

        # Create interpolator
        points = (points_x_flat, points_y_flat)
        interp = scipy_RegularGridInterpolator(
          points,
          values_arr,
          method=grid_interp_method,
          bounds_error=bounds_error,
          fill_value=fill_value,
        )

        # Perform interpolation
        result = interp(xi_arr)

        # Convert result to 2D list (column vector)
        return [[float(val)] for val in result]

      except ValueError as e:
        return f"Error: Invalid input: {e}"
      except Exception as e:
        return f"Error: scipy.interpolate.RegularGridInterpolator error: {e}"
    except Exception as e:
      return f"Error: {str(e)}"

Online Calculator

1D array of x-coordinates of the grid points
1D array of y-coordinates of the grid points
2D array of data values on the grid
Points at which to interpolate data (n_points, 2)
Interpolation method
If True, raise error for out-of-bounds points
Value for out-of-bounds points when bounds_error is False