Chapter 10: SciPy Interpolation
SciPy Interpolation = scipy.interpolate This submodule gives you tools to estimate values between known data points (and sometimes a bit outside them). It’s one of the most frequently used parts of SciPy in experimental science, engineering, data analysis, plotting smooth curves, resampling signals, machine learning feature engineering, and computer graphics.
Current status (February 2026): SciPy 1.17.0 (released January 2026) → scipy.interpolate is very mature. Some older classes like interp1d are now marked legacy (still work perfectly, but won’t get new features), and newer, more consistent APIs are recommended for new code.
Why do we need interpolation? (quick motivation)
You measured temperature at 10 unevenly spaced times during an experiment → you want a smooth curve or value at any arbitrary time. Or you have scattered (x,y,z) measurements → you want to evaluate on a fine regular grid for contour plotting. Or you resample audio / images / time series to a different sampling rate.
SciPy gives you many flavors — from super simple to very sophisticated splines.
Main families of interpolators in scipy.interpolate (2026 view)
| Dimension | Data structure | Most common / recommended classes / functions (2026) | When to reach for it | Speed / smoothness |
|---|---|---|---|---|
| 1D | x sorted (increasing) | interp1d (legacy but still everywhere), make_interp_spline, PchipInterpolator, Akima1DInterpolator, CubicSpline | Classic 1D curves, time series, spectra | Fast → very smooth |
| 1D | x not necessarily sorted | InterpolatedUnivariateSpline (older), or sort first + above | When data is messy | Medium |
| 2D | Regular (structured) grid | RegularGridInterpolator | Gridded simulation output, images, lookup tables | Fast |
| 2D+ | Scattered / unstructured | griddata (convenience), LinearNDInterpolator, CloughTocher2DInterpolator, RBFInterpolator | Experimental scattered points, geospatial data | Medium → slow |
| Any | Radial basis functions | RBFInterpolator | Smooth global fit, noisy data, high dimensions | Slow but flexible |
| Spline basis | Any dimension | make_interp_spline, make_lsq_spline, LSQUnivariateSpline | You want control over knots / smoothing | Medium |
Let’s do practical examples — start simple, build up
Always begin your notebook like this:
|
0 1 2 3 4 5 6 7 8 |
import numpy as np import matplotlib.pyplot as plt from scipy import interpolate |
1. Classic 1D — interp1d (still very widely used, even if legacy)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
# Some noisy temperature measurements x = np.array([0.0, 1.2, 2.5, 3.1, 4.8, 6.0, 7.3]) y = np.array([22.1, 24.8, 27.2, 26.9, 25.4, 23.7, 21.5]) # Create interpolator object f_linear = interpolate.interp1d(x, y, kind='linear') f_cubic = interpolate.interp1d(x, y, kind='cubic') # actually calls CubicSpline under the hood # Fine grid for plotting xnew = np.linspace(0, 7.3, 200) plt.plot(x, y, 'o', ms=8, label='measured') plt.plot(xnew, f_linear(xnew), '-', label='linear') plt.plot(xnew, f_cubic(xnew), '--', label='cubic') plt.legend(); plt.grid(alpha=0.3); plt.xlabel('Time (h)'); plt.ylabel('Temp (°C)') plt.title("interp1d — linear vs cubic"); plt.show() |
→ Cubic usually looks nicer, but can overshoot (Runge phenomenon) if points are uneven or data noisy.
2. Modern & recommended 1D splines (2026 style)
Better control, no legacy warning, boundary conditions, derivatives, etc.
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
# Same data spl = interpolate.make_interp_spline(x, y, k=3) # k=3 → cubic, default BC = not-a-knot # Or more control spl_pchip = interpolate.PchipInterpolator(x, y) # preserves monotonicity (good for positive quantities) spl_akima = interpolate.Akima1DInterpolator(x, y) # less oscillation than cubic xnew = np.linspace(-0.5, 8, 300) # extrapolate a bit plt.plot(x, y, 'o', label='data') plt.plot(xnew, spl(xnew), label='cubic spline (make_interp_spline)') plt.plot(xnew, spl_pchip(xnew), '--', label='PCHIP (shape-preserving)') plt.plot(xnew, spl_akima(xnew), '-.', label='Akima') plt.legend(); plt.grid(alpha=0.3); plt.show() |
PCHIP and Akima are excellent when you don’t want overshoot (e.g. concentrations, cumulative sums, monotonic trends).
3. 2D regular grid — RegularGridInterpolator
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
# Example: temperature on a latitude-longitude grid x = np.linspace(0, 10, 11) # 11 points y = np.linspace(0, 5, 6) X, Y = np.meshgrid(x, y, indexing='ij') Z = np.sin(X/2) * np.cos(Y) + 0.1*np.random.randn(*X.shape) # fake data interp = interpolate.RegularGridInterpolator((x, y), Z, method='linear') # Query arbitrary points points_to_query = np.array([[2.3, 1.1], [7.8, 4.2], [5.0, 2.5]]) values = interp(points_to_query) print("Interpolated values:", values) |
→ Very fast for structured grids (e.g. NetCDF output, image resizing).
4. Scattered 2D data — griddata (quick & dirty) or RBFInterpolator (smooth)
|
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 |
# Scattered points np.random.seed(42) pts = np.random.rand(60, 2) * 10 values = np.sin(pts[:,0]/3) * np.cos(pts[:,1]/2) + 0.15*np.random.randn(60) # Grid for plotting xi = np.linspace(0, 10, 200) yi = np.linspace(0, 10, 200) XI, YI = np.meshgrid(xi, yi) # Quick method — nearest / linear / cubic zi_linear = interpolate.griddata(pts, values, (XI, YI), method='linear') # Smoother — RBF (Gaussian, multiquadric, inverse, etc.) rbf = interpolate.RBFInterpolator(pts, values, kernel='gaussian', epsilon=1.5) zi_rbf = rbf(np.column_stack((XI.ravel(), YI.ravel()))).reshape(XI.shape) # Plot comparison fig, axs = plt.subplots(1, 2, figsize=(10,4)) axs[0].tricontourf(XI, YI, zi_linear, levels=30); axs[0].plot(pts[:,0], pts[:,1], 'k.') axs[0].set_title('griddata linear') axs[1].tricontourf(XI, YI, zi_rbf, levels=30); axs[1].plot(pts[:,0], pts[:,1], 'k.') axs[1].set_title('RBF gaussian') plt.show() |
→ griddata is convenient but can look triangular/artifacts. RBFInterpolator gives beautiful smooth surfaces (but slower + parameter tuning needed).
Quick cheat sheet — which one first? (2026 advice)
- 1D sorted data, want simple → interp1d (still ok) or make_interp_spline
- 1D, hate overshoot → PchipInterpolator or Akima1DInterpolator
- 2D/3D regular grid → RegularGridInterpolator
- Scattered points, quick plot → griddata
- Scattered, want smooth & global → RBFInterpolator (tune kernel & epsilon)
- Need derivatives / integrals / control over knots → make_interp_spline + BSpline basis
Official tutorial is still excellent: https://docs.scipy.org/doc/scipy/tutorial/interpolate.html (especially the 1D, multivariate, RBF sections)
Now — what kind of interpolation are you actually facing or curious about?
- Noisy 1D time series?
- Scattered sensor data?
- Resampling images / audio?
- Need monotonic / shape-preserving?
- High-dimensional lookup table?
Tell me your use-case and we’ll build a tailored, realistic example (maybe even with fake data that looks like yours). 😊
