Reproject, resample & align¶
Three ways to change a raster's grid:
to_crs(epsg)— reproject to another coordinate reference system.resample(cell_size)— change the pixel size (resolution) within the same CRS.align(reference)— snap rows/columns/cell-size/CRS to match another raster. This is the operation you use to make every layer line up with a DEM before modelling.
Setup¶
In [1]:
Copied!
%matplotlib inline
import tempfile
from pathlib import Path
import numpy as np
DATA = Path('../../../examples/data')
WORK = Path(tempfile.mkdtemp(prefix='pyramids-ops-'))
DATA.is_dir(), WORK.is_dir()
%matplotlib inline
import tempfile
from pathlib import Path
import numpy as np
DATA = Path('../../../examples/data')
WORK = Path(tempfile.mkdtemp(prefix='pyramids-ops-'))
DATA.is_dir(), WORK.is_dir()
Out[1]:
(True, True)
In [2]:
Copied!
from pyramids.dataset import Dataset
ds = Dataset.read_file(DATA / 'acc4000.tif')
ds.shape, ds.epsg, ds.cell_size
from pyramids.dataset import Dataset
ds = Dataset.read_file(DATA / 'acc4000.tif')
ds.shape, ds.epsg, ds.cell_size
2026-07-11 14:42:15 | INFO | pyramids.base.config | Logging is configured.
Out[2]:
((1, 13, 14), 32618, 4000.0)
The input raster on its native UTM grid — compare each transformed result below against it.
In [3]:
Copied!
ds.plot(band=0, title="input (EPSG:32618)")
ds.plot(band=0, title="input (EPSG:32618)")
Out[3]:
<cleopatra.array_glyph.ArrayGlyph at 0x7f14d37c8ad0>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
Reproject — to_crs¶
Reproject from UTM (EPSG:32618) to geographic lon/lat (EPSG:4326).
In [4]:
Copied!
wgs84 = ds.to_crs(4326)
wgs84.epsg, wgs84.shape, wgs84.cell_size
wgs84 = ds.to_crs(4326)
wgs84.epsg, wgs84.shape, wgs84.cell_size
Out[4]:
(4326, (1, 13, 14), 0.03611587177268461)
Reprojected to lon/lat — same scene, but the axes are now degrees instead of metres.
In [5]:
Copied!
wgs84.plot(band=0, title="reprojected (EPSG:4326)")
wgs84.plot(band=0, title="reprojected (EPSG:4326)")
Out[5]:
<cleopatra.array_glyph.ArrayGlyph at 0x7f14d396a350>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
Resample — resample¶
Double the cell size; the row/column count roughly halves.
In [6]:
Copied!
coarser = ds.resample(cell_size=ds.cell_size * 2)
coarser.cell_size, coarser.shape
coarser = ds.resample(cell_size=ds.cell_size * 2)
coarser.cell_size, coarser.shape
Out[6]:
(8000.0, (1, 6, 7))
Resampled to double the cell size — the same extent rendered on a coarser grid with blockier pixels.
In [7]:
Copied!
coarser.plot(band=0, title="resampled (8000 m cells)")
coarser.plot(band=0, title="resampled (8000 m cells)")
Out[7]:
<cleopatra.array_glyph.ArrayGlyph at 0x7f14d35bc910>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
Align to a reference — align¶
align copies the reference raster's grid (rows, columns, cell size, CRS) onto the data, so
the two share an identical geotransform — the prerequisite for cell-by-cell raster algebra.
In [8]:
Copied!
reference = ds.resample(cell_size=ds.cell_size * 2) # stand-in reference grid
aligned = ds.align(reference)
aligned.shape == reference.shape, aligned.cell_size == reference.cell_size
reference = ds.resample(cell_size=ds.cell_size * 2) # stand-in reference grid
aligned = ds.align(reference)
aligned.shape == reference.shape, aligned.cell_size == reference.cell_size
Out[8]:
(True, True)
The aligned raster now shares the reference grid exactly, so it lines up cell-for-cell for raster algebra.
In [9]:
Copied!
aligned.plot(band=0, title="aligned to reference")
aligned.plot(band=0, title="aligned to reference")
Out[9]:
<cleopatra.array_glyph.ArrayGlyph at 0x7f14d34883e0>
/home/runner/work/pyramids/pyramids/.pixi/envs/docs/lib/python3.14/site-packages/matplotlib/colors.py:816: RuntimeWarning: overflow encountered in multiply xa *= self.N
Notes¶
to_crs/resampletake amethod=("nearest neighbor","bilinear","cubic"); use nearest for categorical data, bilinear/cubic for continuous.- See also: Crop & mask, Mosaic / merge.