Oven logo

Oven

Published

xarray-based spatial analysis tools

pip install xarray-spatial

Package Downloads

Weekly DownloadsMonthly Downloads

Authors

Project URLs

Requires Python

>=3.12

Latest Release
pypi version conda-forge version
Downloads
PyPI downloads per month conda-forge downloads
License MIT People GitHub contributors
Build Status Coverage

title

:round_pushpin: Fast, Accurate Python library for Raster Operations

:zap: Extensible with Numba

:fast_forward: Scalable with Dask

:confetti_ball: Free of GDAL / GEOS Dependencies

:earth_africa: General-Purpose Spatial Processing, Geared Towards GIS Professionals


Xarray-Spatial implements common raster analysis functions using Numba and provides an easy-to-install, easy-to-extend codebase for raster analysis.

Installation

# via pip
pip install xarray-spatial

# via conda
conda install -c conda-forge xarray-spatial

Downloading our starter examples and data

Once you have xarray-spatial installed in your environment, you can use one of the following in your terminal (with the environment active) to download our examples and/or sample data into your local directory.

xrspatial examples : Download the examples notebooks and the data used.

xrspatial copy-examples : Download the examples notebooks but not the data. Note: you won't be able to run many of the examples.

xrspatial fetch-data : Download just the data and not the notebooks.

In all the above, the command will download and store the files into your current directory inside a folder named 'xrspatial-examples'.

xarray-spatial grew out of the Datashader project, which provides fast rasterization of vector data (points, lines, polygons, meshes, and rasters) for use with xarray-spatial.

xarray-spatial does not depend on GDAL / GEOS, which makes it fully extensible in Python but does limit the breadth of operations that can be covered. xarray-spatial is meant to include the core raster-analysis functions needed for GIS developers / analysts, implemented independently of the non-Python geo stack.

Our documentation is still under construction, but docs can be found here.

Raster-huh?

Rasters are regularly gridded datasets like GeoTIFFs, JPGs, and PNGs.

In the GIS world, rasters are used for representing continuous phenomena (e.g. elevation, rainfall, distance), either directly as numerical values, or as RGB images created for humans to view. Rasters typically have two spatial dimensions, but may have any number of other dimensions (time, type of measurement, etc.)

Supported Spatial Functions with Supported Inputs

āœ… = native backend Ā Ā  šŸ”„ = accepted (CPU fallback)


Classification

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Box PlotClassifies values into bins based on box plot quartile boundariesPySAL mapclassifyāœ…ļøāœ…āœ…šŸ”„
Equal IntervalDivides the value range into equal-width binsPySAL mapclassifyāœ…ļøāœ…āœ…āœ…
Head/Tail BreaksClassifies heavy-tailed distributions using recursive mean splittingPySAL mapclassifyāœ…ļøāœ…šŸ”„šŸ”„
Maximum BreaksFinds natural groupings by maximizing differences between sorted valuesPySAL mapclassifyāœ…ļøāœ…šŸ”„šŸ”„
Natural BreaksOptimizes class boundaries to minimize within-class variance (Jenks)Jenks 1967, PySALāœ…ļøāœ…šŸ”„šŸ”„
PercentilesAssigns classes based on user-defined percentile breakpointsPySAL mapclassifyāœ…ļøāœ…āœ…šŸ”„
QuantileDistributes values into classes with equal observation countsPySAL mapclassifyāœ…ļøāœ…āœ…šŸ”„
ReclassifyRemaps pixel values to new classes using a user-defined lookupPySAL mapclassifyāœ…ļøāœ…āœ…āœ…
Std MeanClassifies values by standard deviation intervals from the meanPySAL mapclassifyāœ…ļøāœ…āœ…āœ…

Diffusion

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
DiffuseRuns explicit forward-Euler diffusion on a 2D scalar fieldStandard (heat equation)āœ…ļøāœ…ļøāœ…ļøāœ…ļø

Focal

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ApplyApplies a custom function over a sliding neighborhood windowStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
HotspotsIdentifies statistically significant spatial clusters using Getis-Ord Gi*Getis & Ord 1992āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Emerging HotspotsClassifies time-series hot/cold spot trends using Gi* and Mann-KendallGetis & Ord 1992, Mann 1945āœ…ļøāœ…ļøāœ…ļøāœ…ļø
MeanComputes the mean value within a sliding neighborhood windowStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Focal StatisticsComputes summary statistics over a sliding neighborhood windowStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
BilateralFeature-preserving smoothing via bilateral filteringTomasi & Manduchi 1998āœ…ļøāœ…ļøāœ…ļøāœ…ļø
GLCM TextureComputes Haralick GLCM texture features over a sliding windowHaralick et al. 1973āœ…ļøāœ…ļøšŸ”„šŸ”„

Morphological

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ErodeMorphological erosion (local minimum over structuring element)Standard (morphology)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
DilateMorphological dilation (local maximum over structuring element)Standard (morphology)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
OpeningErosion then dilation (removes small bright features)Standard (morphology)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
ClosingDilation then erosion (fills small dark gaps)Standard (morphology)āœ…ļøāœ…ļøāœ…ļøāœ…ļø

Fire

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
dNBRDifferenced Normalized Burn Ratio (pre minus post NBR)USGSāœ…ļøāœ…ļøāœ…ļøāœ…ļø
RdNBRRelative dNBR normalized by pre-fire vegetation densityUSGSāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Burn Severity ClassUSGS 7-class burn severity from dNBR thresholdsUSGSāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Fireline IntensityByram's fireline intensity from fuel load and spread rate (kW/m)Byram 1959āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Flame LengthFlame length derived from fireline intensity (m)Byram 1959āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Rate of SpreadSimplified Rothermel spread rate with Anderson 13 fuel models (m/min)Rothermel 1972, Anderson 1982āœ…ļøāœ…ļøāœ…ļøāœ…ļø
KBDIKeetch-Byram Drought Index single time-step update (0-800 mm)Keetch & Byram 1968āœ…ļøāœ…ļøāœ…ļøāœ…ļø

Multispectral

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Atmospherically Resistant Vegetation Index (ARVI)Vegetation index resistant to atmospheric effects using blue band correctionKaufman & Tanre 1992āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Enhanced Built-Up and Bareness Index (EBBI)Highlights built-up areas and barren land from thermal and SWIR bandsAs-syakur et al. 2012āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Enhanced Vegetation Index (EVI)Enhanced vegetation index reducing soil and atmospheric noiseHuete et al. 2002āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Green Chlorophyll Index (GCI)Estimates leaf chlorophyll content from green and NIR reflectanceGitelson et al. 2003āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Normalized Burn Ratio (NBR)Measures burn severity using NIR and SWIR band differenceUSGS Landsatāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Normalized Burn Ratio 2 (NBR2)Refines burn severity mapping using two SWIR bandsUSGS Landsatāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Normalized Difference Moisture Index (NDMI)Detects vegetation moisture stress from NIR and SWIR reflectanceUSGS Landsatāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Normalized Difference Water Index (NDWI)Maps open water bodies using green and NIR band differenceMcFeeters 1996āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Modified Normalized Difference Water Index (MNDWI)Detects water in urban areas using green and SWIR bandsXu 2006āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Normalized Difference Vegetation Index (NDVI)Quantifies vegetation density from red and NIR band differenceRouse et al. 1973āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Soil Adjusted Vegetation Index (SAVI)Vegetation index with soil brightness correction factorHuete 1988āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Structure Insensitive Pigment Index (SIPI)Estimates carotenoid-to-chlorophyll ratio for plant stress detectionPenuelas et al. 1995āœ…ļøāœ…ļøāœ…ļøāœ…ļø
True ColorComposites red, green, and blue bands into a natural color imageStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø

Multivariate

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Mahalanobis DistanceMeasures statistical distance from a multi-band reference distribution, accounting for band correlationsMahalanobis 1936āœ…ļøāœ…ļøāœ…ļøāœ…ļø

Pathfinding

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
A* PathfindingFinds the least-cost path between two cells on a cost surfaceHart et al. 1968āœ…ļøāœ…šŸ”„šŸ”„
Multi-Stop SearchRoutes through N waypoints in sequence, with optional TSP reorderingCustomāœ…ļøāœ…šŸ”„šŸ”„

Proximity

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
AllocationAssigns each cell to the identity of the nearest source featureStandard (Dijkstra)āœ…ļøāœ…āœ…ļøāœ…ļø
Balanced AllocationPartitions a cost surface into territories of roughly equal cost-weighted areaCustomāœ…ļøāœ…āœ…ļøāœ…ļø
Cost DistanceComputes minimum accumulated cost to the nearest source through a friction surfaceStandard (Dijkstra)āœ…ļøāœ…āœ…ļøāœ…ļø
Least-Cost CorridorIdentifies zones of low cumulative cost between two source locationsStandard (Dijkstra)āœ…ļøāœ…āœ…ļøāœ…ļø
DirectionComputes the direction from each cell to the nearest source featureStandardāœ…ļøāœ…āœ…ļøāœ…ļø
ProximityComputes the distance from each cell to the nearest source featureStandardāœ…ļøāœ…āœ…ļøāœ…ļø
Surface DistanceComputes distance along the 3D terrain surface to the nearest sourceStandard (Dijkstra)āœ…ļøāœ…āœ…ļøāœ…ļø
Surface AllocationAssigns each cell to the nearest source by terrain surface distanceStandard (Dijkstra)āœ…ļøāœ…āœ…ļøāœ…ļø
Surface DirectionComputes compass direction to the nearest source by terrain surface distanceStandard (Dijkstra)āœ…ļøāœ…āœ…ļøāœ…ļø

Raster / Vector Conversion

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
PolygonizeConverts contiguous regions of equal value into vector polygonsStandard (CCL)āœ…ļøāœ…ļøāœ…ļøšŸ”„
ContoursExtracts elevation contour lines (isolines) from a raster surfaceStandard (marching squares)āœ…ļøāœ…ļøšŸ”„šŸ”„
RasterizeRasterizes vector geometries (polygons, lines, points) from a GeoDataFrameStandard (scanline, Bresenham)āœ…ļøāœ…ļø

Surface

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
AspectComputes downslope direction of each cell in degreesHorn 1981āœ…ļøāœ…ļøāœ…ļøāœ…ļø
CurvatureMeasures rate of slope change (concavity/convexity) at each cellZevenbergen & Thorne 1987āœ…ļøāœ…ļøāœ…ļøāœ…ļø
HillshadeSimulates terrain illumination from a given sun angle and azimuthGDAL gdaldemāœ…ļøāœ…ļøāœ…ļøāœ…ļø
RoughnessComputes local relief as max minus min elevation in a 3Ɨ3 windowGDAL gdaldemāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Sky-View FactorMeasures the fraction of visible sky hemisphere at each cellZakek et al. 2011āœ…ļøāœ…ļøāœ…ļøāœ…ļø
SlopeComputes terrain gradient steepness at each cell in degreesHorn 1981āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Terrain GenerationGenerates synthetic terrain from fBm or ridged fractal noise with optional domain warping, Worley blending, and hydraulic erosionCustom (fBm)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
TPIComputes Topographic Position Index (center minus mean of neighbors)Weiss 2001āœ…ļøāœ…ļøāœ…ļøāœ…ļø
TRIComputes Terrain Ruggedness Index (local elevation variation)Riley et al. 1999āœ…ļøāœ…ļøāœ…ļøāœ…ļø
LandformsClassifies terrain into 10 landform types using the Weiss (2001) TPI schemeWeiss 2001āœ…ļøāœ…ļøāœ…ļøāœ…ļø
ViewshedDetermines visible cells from a given observer point on terrainGRASS GIS r.viewshedāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Min Observable HeightFinds the minimum observer height needed to see each cell (experimental)Customāœ…ļø
Perlin NoiseGenerates smooth continuous random noise for procedural texturesPerlin 1985āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Worley NoiseGenerates cellular (Voronoi) noise returning distance to the nearest feature pointWorley 1996āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Hydraulic ErosionSimulates particle-based water erosion to carve valleys and deposit sedimentCustomāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Bump MappingAdds randomized bump features to simulate natural terrain variationCustomāœ…ļøāœ…ļøāœ…ļøāœ…ļø

Hydrology

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Flow Direction (D8)Computes D8 flow direction from each cell toward the steepest downhill neighborO'Callaghan & Mark 1984āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Flow Direction (Dinf)Computes D-infinity flow direction as a continuous angle toward the steepest downslope facetTarboton 1997āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Flow Direction (MFD)Partitions flow to all downslope neighbors with an adaptive exponent (Qin et al. 2007)Qin et al. 2007āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Flow Accumulation (D8)Counts upstream cells draining through each cell in a D8 flow direction gridJenson & Domingue 1988āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Flow Accumulation (MFD)Accumulates upstream area through all MFD flow paths weighted by directional fractionsQin et al. 2007āœ…ļøāœ…ļøāœ…ļøšŸ”„
WatershedLabels each cell with the pour point it drains to via D8 flow directionStandard (D8 tracing)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
BasinsDelineates drainage basins by labeling each cell with its outlet IDStandard (D8 tracing)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Stream OrderAssigns Strahler or Shreve stream order to cells in a drainage networkStrahler 1957, Shreve 1966āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Stream Order (Dinf)Strahler/Shreve stream ordering on D-infinity flow direction gridsTarboton 1997āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Stream Order (MFD)Strahler/Shreve stream ordering on MFD fraction gridsFreeman 1991āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Stream LinkAssigns unique IDs to each stream segment between junctionsStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Stream Link (Dinf)Stream link segmentation on D-infinity flow direction gridsTarboton 1997āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Stream Link (MFD)Stream link segmentation on MFD fraction gridsFreeman 1991āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Snap Pour PointSnaps pour points to the highest-accumulation cell within a search radiusCustomāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Flow PathTraces downstream flow paths from start points through a D8 direction gridStandard (D8 tracing)āœ…ļøāœ…ļøšŸ”„šŸ”„
HANDComputes Height Above Nearest Drainage by tracing D8 flow to the nearest stream cellNobre et al. 2011āœ…ļøāœ…ļøšŸ”„šŸ”„
TWITopographic Wetness Index: ln(specific catchment area / tan(slope))Beven & Kirkby 1979āœ…ļøāœ…ļøāœ…ļøšŸ”„

Flood

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
Flood DepthComputes water depth above terrain from a HAND raster and water levelStandard (HAND-based)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
InundationProduces a binary flood/no-flood mask from a HAND raster and water levelStandard (HAND-based)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
Curve Number RunoffEstimates runoff depth from rainfall using the SCS/NRCS curve number methodSCS/NRCSāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Travel TimeEstimates overland flow travel time via simplified Manning's equationManning 1891āœ…ļøāœ…ļøāœ…ļøāœ…ļø

Interpolation

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
IDWInverse Distance Weighting from scattered points to a raster gridStandard (IDW)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
KrigingOrdinary Kriging with automatic variogram fitting (spherical, exponential, gaussian)Standard (ordinary kriging)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
SplineThin Plate Spline interpolation with optional smoothingStandard (TPS)āœ…ļøāœ…ļøāœ…ļøāœ…ļø

Zonal

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
ApplyApplies a custom function to each zone in a classified rasterStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
CropExtracts the bounding rectangle of a specific zoneStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
RegionsIdentifies connected regions of non-zero cellsStandard (CCL)āœ…ļøāœ…ļøāœ…ļøāœ…ļø
TrimRemoves nodata border rows and columns from a rasterStandardāœ…ļøāœ…ļøāœ…ļøāœ…ļø
Zonal StatisticsComputes summary statistics for a value raster within each zoneStandardāœ…ļøāœ…ļøāœ…ļøšŸ”„
Zonal Cross TabulateCross-tabulates agreement between two categorical rastersStandardāœ…ļøāœ…ļøšŸ”„šŸ”„

Utilities

NameDescriptionSourceNumPy xr.DataArrayDask xr.DataArrayCuPy GPU xr.DataArrayDask GPU xr.DataArray
PreviewDownsamples a raster to target pixel dimensions for visualizationCustomāœ…ļøāœ…ļøāœ…ļøšŸ”„

Usage

Quick Start

Importing xrspatial registers an .xrs accessor on DataArrays and Datasets, giving you tab-completable access to every spatial operation:

import numpy as np
import xarray as xr
import xrspatial

# Create or load a raster
elevation = xr.DataArray(np.random.rand(100, 100) * 1000, dims=['y', 'x'])

# Surface analysis — call operations directly on the DataArray
slope = elevation.xrs.slope()
hillshaded = elevation.xrs.hillshade(azimuth=315, angle_altitude=45)
aspect = elevation.xrs.aspect()

# Classification
classes = elevation.xrs.equal_interval(k=5)
breaks = elevation.xrs.natural_breaks(k=10)

# Proximity
distance = elevation.xrs.proximity(target_values=[1])

# Multispectral — call on the NIR band, pass other bands as arguments
nir = xr.DataArray(np.random.rand(100, 100), dims=['y', 'x'])
red = xr.DataArray(np.random.rand(100, 100), dims=['y', 'x'])
blue = xr.DataArray(np.random.rand(100, 100), dims=['y', 'x'])

vegetation = nir.xrs.ndvi(red)
enhanced_vi = nir.xrs.evi(red, blue)
Dataset Support

The .xrs accessor works on Datasets too. Single-input functions apply the operation to each data variable. Multi-input functions (multispectral indices) accept string kwargs that map band aliases to variable names:

ds = xr.Dataset({'band_4': red, 'band_5': nir})

# Single-input: slope computed for each variable
slope_ds = ds.xrs.slope()

# Multi-input: map variable names to band parameters
ndvi_result = ds.xrs.ndvi(nir='band_5', red='band_4')
Function Import Style

All operations are also available as standalone functions if you prefer explicit imports:

from xrspatial import hillshade, slope, ndvi

hillshaded = hillshade(elevation)
slope_result = slope(elevation)
vegetation = ndvi(nir, red)

Check out the user guide here.


title title

Dependencies

xarray-spatial currently depends on Datashader, but will soon be updated to depend only on xarray and numba, while still being able to make use of Datashader output when available.

title

Notes on GDAL

Within the Python ecosystem, many geospatial libraries interface with the GDAL C++ library for raster and vector input, output, and analysis (e.g. rasterio, rasterstats, geopandas). GDAL is robust, performant, and has decades of great work behind it. For years, off-loading expensive computations to the C/C++ level in this way has been a key performance strategy for Python libraries (obviously...Python itself is implemented in C!).

However, wrapping GDAL has a few drawbacks for Python developers and data scientists:

  • GDAL can be a pain to build / install.
  • GDAL is hard for Python developers/analysts to extend, because it requires understanding multiple languages.
  • GDAL's data structures are defined at the C/C++ level, which constrains how they can be accessed from Python.

With the introduction of projects like Numba, Python gained new ways to provide high-performance code directly in Python, without depending on or being constrained by separate C/C++ extensions. xarray-spatial implements algorithms using Numba and Dask, making all of its source code available as pure Python without any "black box" barriers that obscure what is going on and prevent full optimization. Projects can make use of the functionality provided by xarray-spatial where available, while still using GDAL where required for other tasks.

Citation

Cite this code:

xarray-contrib/xarray-spatial, https://github.com/xarray-contrib/xarray-spatial, ©2020-2026.