Crop & mask¶
Restrict a raster to an area of interest:
crop(mask=vector)— clip to polygon geometry (everything outside becomes no-data).crop(bbox=..., epsg=...)— clip to a rectangular bounding box.get_mask()— the boolean valid-data mask (True where a cell holds real data).
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
from pyramids.feature import FeatureCollection
ds = Dataset.read_file(DATA / 'acc4000.tif')
polys = FeatureCollection.read_file(DATA / 'coello_polygons.geojson')
ds.shape, ds.epsg, (len(polys), polys.epsg)
from pyramids.dataset import Dataset
from pyramids.feature import FeatureCollection
ds = Dataset.read_file(DATA / 'acc4000.tif')
polys = FeatureCollection.read_file(DATA / 'coello_polygons.geojson')
ds.shape, ds.epsg, (len(polys), polys.epsg)
2026-07-11 14:41:35 | INFO | pyramids.base.config | Logging is configured.
Out[2]:
((1, 13, 14), 32618, (4, 32618))
The full input raster — every cropped result below is a subset of this extent.
In [3]:
Copied!
ds.plot(band=0, title="input raster")
ds.plot(band=0, title="input raster")
Out[3]:
<cleopatra.array_glyph.ArrayGlyph at 0x7fbbfb0596a0>
/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
Crop to polygons — crop(mask=...)¶
The raster shrinks to the polygons' envelope; cells outside the polygons are set to no-data.
In [4]:
Copied!
clipped = ds.crop(mask=polys)
clipped.shape, clipped.epsg
clipped = ds.crop(mask=polys)
clipped.shape, clipped.epsg
Out[4]:
((1, 5, 8), 32618)
After the polygon crop the grid shrinks to the polygons' envelope and cells outside them are no-data.
In [5]:
Copied!
clipped.plot(band=0, title="cropped to polygons")
clipped.plot(band=0, title="cropped to polygons")
Out[5]:
<cleopatra.array_glyph.ArrayGlyph at 0x7fbbfb1d39d0>
/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
Crop to a bounding box — crop(bbox=...)¶
Keep only the inner half of the raster's extent.
In [6]:
Copied!
xmin, ymin, xmax, ymax = ds.bbox
dx, dy = (xmax - xmin) / 4, (ymax - ymin) / 4
inner = ds.crop(bbox=(xmin + dx, ymin + dy, xmax - dx, ymax - dy), epsg=ds.epsg)
inner.shape
xmin, ymin, xmax, ymax = ds.bbox
dx, dy = (xmax - xmin) / 4, (ymax - ymin) / 4
inner = ds.crop(bbox=(xmin + dx, ymin + dy, xmax - dx, ymax - dy), epsg=ds.epsg)
inner.shape
Out[6]:
(1, 7, 7)
The bbox crop keeps only the inner rectangle of the original extent.
In [7]:
Copied!
inner.plot(band=0, title="cropped to bbox")
inner.plot(band=0, title="cropped to bbox")
Out[7]:
<cleopatra.array_glyph.ArrayGlyph at 0x7fbbfab4fd90>
/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
The valid-data mask — get_mask¶
A GDAL-style mask: nonzero (255) where the cell holds data, 0 where it is no-data.
In [8]:
Copied!
mask = ds.get_mask()
valid = int((mask > 0).sum())
mask.shape, valid, 'valid of', mask.size
mask = ds.get_mask()
valid = int((mask > 0).sum())
mask.shape, valid, 'valid of', mask.size
Out[8]:
((13, 14), 89, 'valid of', 182)
Notes¶
cropaccepts aFeatureCollectionor a GeoDataFrame as the mask; passtouch=Falseto keep only cells whose centre falls inside the geometry.- See also: Reproject / resample / align, Zonal statistics.