{
  "__type": "IngestedDoc",
  "__tag": 4010,
  "_content": {},
  "_ordered_sections": [],
  "item_file": null,
  "item_line": null,
  "item_type": null,
  "aliases": [],
  "example_section_data": {
    "__type": "Section",
    "__tag": 4015,
    "children": [],
    "title": [],
    "level": 0,
    "target": null
  },
  "see_also": [],
  "signature": null,
  "references": null,
  "qa": "tutorial:interpolate:ND_regular_grid",
  "arbitrary": [
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Target",
          "__tag": 4061,
          "label": "tutorial-interpolate_regular_grid_interpolator"
        }
      ],
      "title": [],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Suppose you have N-dimensional data on a regular grid, and you want to interpolate it. In such a case, "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "RegularGridInterpolator",
              "domain": null,
              "role": "class",
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " can be useful. Several interpolation strategies are supported: nearest-neighbor, linear, and tensor product splines of odd degree."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Strictly speaking, this class efficiently handles data given on "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "rectilinear"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " grids: hypercubic lattices with possibly unequal spacing between points. The number of points per dimension can be different for different dimensions."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "The following example demonstrates its use, and compares the interpolation results using each method."
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": ">>> import numpy as np\n>>> import matplotlib.pyplot as plt\n>>> from scipy.interpolate import RegularGridInterpolator\n\nSuppose we want to interpolate this 2-D function.\n\n>>> def F(u, v):\n...     return u * np.cos(u * v) + v * np.sin(u * v)\n\nSuppose we only know some data on a regular grid.\n\n>>> fit_points = [np.linspace(0, 3, 8), np.linspace(0, 3, 11)]\n>>> values = F(*np.meshgrid(*fit_points, indexing='ij'))\n\nCreating test points and true values for evaluations.\n\n>>> ut, vt = np.meshgrid(np.linspace(0, 3, 80), np.linspace(0, 3, 80), indexing='ij')\n>>> true_values = F(ut, vt)\n>>> test_points = np.array([ut.ravel(), vt.ravel()]).T\n\nWe can create the interpolator and interpolate test points using each method.\n\n>>> interp = RegularGridInterpolator(fit_points, values)\n>>> fig, axes = plt.subplots(2, 3, figsize=(10, 6))\n>>> axes = axes.ravel()\n>>> fig_index = 0\n>>> for method in ['linear', 'nearest', 'slinear', 'cubic', 'quintic']:\n...     im = interp(test_points, method=method).reshape(80, 80)\n...     axes[fig_index].imshow(im)\n...     axes[fig_index].set_title(method)\n...     axes[fig_index].axis(\"off\")\n...     fig_index += 1\n>>> axes[fig_index].imshow(true_values)\n>>> axes[fig_index].set_title(\"True values\")\n>>> fig.tight_layout()\n>>> fig.show()\n\nAs expected, the higher degree spline interpolations are closest to the\ntrue values, though are more expensive to compute than with `linear`\nor `nearest`. The `slinear` interpolation also matches the `linear`\ninterpolation.",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "If your data is such that spline methods produce ringing, you may consider using "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "method=\"pchip\""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", which uses the tensor product of PCHIP interpolators, a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "PchipInterpolator",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " per dimension."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "If you prefer a functional interface opposed to explicitly creating a class instance, the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "interpn",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " convenience function offers the equivalent functionality."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Specifically, these two forms give identical results:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> from scipy.interpolate import interpn\n>>> rgi = RegularGridInterpolator(fit_points, values)\n>>> result_rgi = rgi(test_points)",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "and"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> result_interpn = interpn(fit_points, values, test_points)\n>>> np.allclose(result_rgi, result_interpn, atol=1e-15)\nTrue",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For data confined to an (N-1)-dimensional subspace of N-dimensional space, i.e. when one of the grid axes has length 1, the extrapolation along this axis is controlled by the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "fill_value"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " keyword parameter:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> x = np.array([0, 5, 10])\n>>> y = np.array([0])\n>>> data = np.array([[0], [5], [10]])\n>>> rgi = RegularGridInterpolator((x, y), data,\n...                               bounds_error=False, fill_value=None)\n>>> rgi([(2, 0), (2, 1), (2, -1)])   # extrapolates the value on the axis\narray([2., 2., 2.])\n>>> rgi.fill_value = -101\n>>> rgi([(2, 0), (2, 1), (2, -1)])\narray([2., -101., -101.])",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Admonition",
          "__tag": 4056,
          "kind": "note",
          "base_type": "note",
          "children": [
            {
              "__type": "AdmonitionTitle",
              "__tag": 4055,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "note "
                }
              ]
            },
            {
              "__type": "Paragraph",
              "__tag": 4045,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "If the input data is such that input dimensions have incommensurate units and differ by many orders of magnitude, the interpolant may have numerical artifacts. Consider rescaling the data before interpolating."
                }
              ]
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Multivariate data interpolation on a regular grid  ("
        },
        {
          "__type": "InlineRole",
          "__tag": 4003,
          "value": "RegularGridInterpolator",
          "domain": null,
          "role": "class",
          "inventory": null
        },
        {
          "__type": "Text",
          "__tag": 4046,
          "value": ")"
        }
      ],
      "level": 0,
      "target": null
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Suppose you have a vector function "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "f(x) = y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", where "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "y"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " are vectors, potentially of different lengths, and you want to sample the function on a grid of "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " values. One way to address this is to use the fact that "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "RegularGridInterpolator",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " allows "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "values"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " with "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "trailing"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " dimensions."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In accordance with how "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "1D interpolators interpret multidimensional arrays",
              "reference": {
                "__type": "LocalRef",
                "__tag": 4022,
                "kind": "docs",
                "path": "tutorial:interpolate:1D"
              },
              "kind": "exists"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ", the interpretation is that the first "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "N"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " dimensions of the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "values"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " arrays are data dimensions (i.e. they correspond to the points defined by the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "grid"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " argument), and the "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "trailing"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " dimensions are batch axes. Note that this disagrees with a usual NumPy broadcasting conventions, where broadcasting proceeds along the "
            },
            {
              "__type": "Emphasis",
              "__tag": 4047,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "leading"
                }
              ]
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " dimensions."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "To illustrate:"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> n = 5   # the number of batch components",
              "execution_status": null
            },
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> # make a 3D grid\n>>> x1 = np.linspace(-np.pi, np.pi, 10)\n>>> x2 = np.linspace(0.0, np.pi, 15)\n>>> x3 = np.linspace(0.0, np.pi/2, 20)\n>>> points = (x1, x2, x3)\n>>>\n>>> # define a function and sample it on the grid\n>>> def f(x1, x2, x3, n):\n...     lst = [np.sin(np.pi*x1/2) * np.exp(x2/2) + x3 + i for i in range(n)]\n...     return np.asarray(lst)\n>>>\n>>> X1, X2, X3 = np.meshgrid(x1, x2, x3, indexing=\"ij\")\n>>> values = f(X1, X2, X3, n)\n>>> values.shape\n(5, 10, 15, 20)\n>>> \n>>> # prepare the data and construct the interpolator\n>>> values = np.moveaxis(values, 0, -1)\n>>> values.shape\n(10, 15, 20, 5)     # the batch dimension is 5\n>>> rgi = RegularGridInterpolator(points, values)\n>>>\n>>> # Coordinates to compute the interpolation at\n>>> x = np.asarray([0.2, np.pi/2.1, np.pi/4.1])\n>>>\n# evaluate\n>>> rgi(x).shape\n(1, 5)",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "In this example, we evaluated a batch of "
            },
            {
              "__type": "InlineMath",
              "__tag": 4057,
              "value": "n=5"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " functions on a three-dimensional grid. In general, multiple batching dimensions are allowed, and the shape of the result follows by appending the batching shape (in this example, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "(5,)"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ") to the shape of the input "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "x"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " (in this example, "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "(1,)'",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ")."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Batch dimensions of "
        },
        {
          "__type": "InlineCode",
          "__tag": 4051,
          "value": "values"
        }
      ],
      "level": 1,
      "target": "tutorial-interpolate_RGI_batching"
    },
    {
      "__type": "Section",
      "__tag": 4015,
      "children": [
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "If you are dealing with data on Cartesian grids with integer coordinates, e.g. resampling image data, these routines may not be the optimal choice. Consider using "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "scipy.ndimage.map_coordinates",
              "reference": {
                "__type": "RefInfo",
                "__tag": 4000,
                "module": "scipy",
                "version": "*",
                "kind": "api",
                "path": "scipy.ndimage._interpolation:map_coordinates"
              },
              "kind": "module"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " instead."
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "For floating-point data on grids with equal spacing, "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "map_coordinates"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " can be easily wrapped into a "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "RegularGridInterpolator",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " look-alike. The following is a bare-bones example originating from "
            },
            {
              "__type": "Link",
              "__tag": 4049,
              "children": [
                {
                  "__type": "Text",
                  "__tag": 4046,
                  "value": "the Johanness Buchner's 'regulargrid' package"
                }
              ],
              "url": "https://github.com/JohannesBuchner/regulargrid/",
              "title": ""
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":      "
            }
          ]
        },
        {
          "__type": "Code",
          "__tag": 4050,
          "value": "class CartesianGridInterpolator:\n    def __init__(self, points, values, method='linear'):\n        self.limits = np.array([[min(x), max(x)] for x in points])\n        self.values = np.asarray(values, dtype=float)\n        self.order = {'linear': 1, 'cubic': 3, 'quintic': 5}[method]\n\n    def __call__(self, xi):\n        \"\"\"\n        `xi` here is an array-like (an array or a list) of points.\n\n        Each \"point\" is an ndim-dimensional array_like, representing\n        the coordinates of a point in ndim-dimensional space.\n        \"\"\"\n        # transpose the xi array into the ``map_coordinates`` convention\n        # which takes coordinates of a point along columns of a 2D array.\n        xi = np.asarray(xi).T\n\n        # convert from data coordinates to pixel coordinates\n        ns = self.values.shape\n        coords = [(n-1)*(val - lo) / (hi - lo)\n                  for val, n, (lo, hi) in zip(xi, ns, self.limits)]\n\n        # interpolate\n        return map_coordinates(self.values, coords, \n                               order=self.order,\n                               cval=np.nan)  # fill_value",
          "execution_status": null
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "This wrapper can be used as a(n almost) drop-in replacement for the "
            },
            {
              "__type": "InlineRole",
              "__tag": 4003,
              "value": "RegularGridInterpolator",
              "domain": null,
              "role": null,
              "inventory": null
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ":"
            }
          ]
        },
        {
          "__type": "Blockquote",
          "__tag": 4059,
          "children": [
            {
              "__type": "Code",
              "__tag": 4050,
              "value": ">>> x, y = np.arange(5), np.arange(6)\n>>> xx, yy = np.meshgrid(x, y, indexing='ij')\n>>> values = xx**3 + yy**3\n>>> rgi = RegularGridInterpolator((x, y), values, method='linear')\n>>> rgi([[1.5, 1.5], [3.5, 2.6]])\narray([ 9. , 64.9])\n>>> cgi = CartesianGridInterpolator((x, y), values, method='linear')\n>>> cgi([[1.5, 1.5], [3.5, 2.6]])\narray([ 9. , 64.9])",
              "execution_status": null
            }
          ]
        },
        {
          "__type": "Paragraph",
          "__tag": 4045,
          "children": [
            {
              "__type": "Text",
              "__tag": 4046,
              "value": "Note that the example above uses the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "map_coordinates"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " boundary conditions. Thus, results of the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "cubic"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " and "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "quintic"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " interpolations may differ from those of the "
            },
            {
              "__type": "InlineCode",
              "__tag": 4051,
              "value": "RegularGridInterpolator"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": ".  Refer to "
            },
            {
              "__type": "CrossRef",
              "__tag": 4002,
              "value": "scipy.ndimage.map_coordinates",
              "reference": {
                "__type": "RefInfo",
                "__tag": 4000,
                "module": "scipy",
                "version": "*",
                "kind": "api",
                "path": "scipy.ndimage._interpolation:map_coordinates"
              },
              "kind": "module"
            },
            {
              "__type": "Text",
              "__tag": 4046,
              "value": " documentation for more details on boundary conditions and other additional arguments. Finally, we note that this simplified example assumes that the input data is given in the ascending order."
            }
          ]
        }
      ],
      "title": [
        {
          "__type": "Text",
          "__tag": 4046,
          "value": "Uniformly spaced data"
        }
      ],
      "level": 1,
      "target": "tutorial-interpolate_cartesian-grids"
    }
  ],
  "local_refs": []
}