Short answer
Aspect is the compass direction that a slope faces — specifically, the azimuth of the steepest downhill direction at each cell of a digital elevation model (DEM), reported in degrees clockwise from north (0 deg = north, 90 deg = east, 180 deg = south, 270 deg = west). It is the direction component of the terrain gradient; slope is the magnitude component. Both are derived from the same calculation over a cell and its neighbours, so aspect is only meaningful where slope is large enough to define a stable downhill direction.
Where the surface is flat, there is no downhill direction, so tools output a flat code (commonly -1) or NoData. The single most common mistake is reading aspect as if it were a normal linear raster — it is circular, so 359 deg and 1 deg are 2 deg apart, not 358 deg apart.
How aspect is computed
Most GIS tools (Esri Spatial Analyst, GDAL gdaldem, QGIS) estimate the gradient with a 3×3 moving window using Horn's method (the same algorithm Esri popularised). For a centre cell, the eight surrounding elevations (labelled a–i, with e in the centre) feed two finite-difference derivatives:
dz/dx = ((c + 2f + i) - (a + 2d + g)) / (8 * cellsize_x)
dz/dy = ((g + 2h + i) - (a + 2b + c)) / (8 * cellsize_y)
Aspect is then the direction of that gradient vector, converted to a compass azimuth (clockwise from north), typically via atan2. Slope is atan(sqrt((dz/dx)^2 + (dz/dy)^2)). Two consequences follow directly:
- Aspect depends on cell size: a 30 m SRTM tile and a 1 m lidar DEM of the same hillside can give different aspects because the 3×3 window samples different ground.
- Aspect is noise-sensitive. Because it is derived from small elevation differences, sensor noise, interpolation artefacts, and "stair-stepping" in integer DEMs produce speckled aspect rasters, especially on gentle terrain.
The flat-cell problem and the -1 code
When dz/dx and dz/dy are both (near) zero, the gradient vector has no direction. There is genuinely no answer to "which way does this flat cell face." Conventions differ:
- GDAL
gdaldem aspectoutputs -1 for flat cells by default; you can force a fixed value with-zero_for_flat(outputs 0). - Esri Aspect returns -1 for flat areas.
- Some workflows assign NoData, which is cleaner for statistics because flat cells are then excluded automatically.
Practically, do not let -1 leak into a colour ramp or a zonal statistic — it will either paint flats a misleading colour or drag a circular mean toward an arbitrary value. Mask flats out (or reclass -1 to NoData) before any directional analysis.
Why circularity changes everything
Aspect lives on a circle, so ordinary linear maths is wrong:
- Averaging. The arithmetic mean of 350 deg and 10 deg is 180 deg (due south) — exactly backwards from the true answer of 0 deg (north). To average directions you must convert to unit vectors, sum the sines and cosines, and take
atan2(mean_sin, mean_cos). This is the circular mean, and the length of the resultant vector also gives you a measure of directional consistency. - Styling. Use a cyclic / hue-wheel colour ramp so 0 deg and 360 deg map to the same colour. A linear blue-to-red ramp makes north and "just west of north" look maximally different, which is visually false.
- Reclassification. Binning into 8 or 16 compass sectors (N, NE, E, ...) is usually more interpretable than continuous degrees, but remember the north bin wraps: north is typically 337.5–360 and 0–22.5 deg.
Worked example: north-facing slopes for a snow study
Goal: find slopes steeper than 15 deg that face north (within 45 deg of due north) on a 10 m DEM, for a snow-persistence assessment.
GDAL:
# Aspect and slope from the DEM (compute_edges keeps the border)
gdaldem aspect dem_10m.tif aspect.tif -compute_edges
gdaldem slope dem_10m.tif slope.tif -compute_edges # degrees by default
# North-facing AND steep, using gdal_calc (Python)
gdal_calc.py -A aspect.tif -B slope.tif --outfile=north_steep.tif \
--calc="( ((A>=315)|(A<=45)) & (B>=15) & (A!=-1) ) * 1" --NoDataValue=0
The (A>=315)|(A<=45) clause handles the wrap-around at north; the A!=-1 clause drops flat cells.
QGIS Processing: run Aspect (gdal:aspect or native:aspect) and Slope (native:slope), then Raster calculator with the same logical expression. For per-polygon summaries (e.g. mean aspect of each catchment), do not use ordinary Zonal Statistics on the aspect raster — instead compute sin and cos rasters of the aspect, run zonal mean on each, and recombine with atan2.
What aspect is good for
Aspect drives any process with a directional energy or moisture component: solar insolation (south-facing slopes in the northern hemisphere receive more direct radiation; the asymmetry is strongest at mid-latitudes), snow persistence, soil moisture and vegetation banding, frost weathering, and slope stability where bedding or joint orientation interacts with slope direction. In geology it helps interpret structural grain, differential weathering, and the orientation of dip slopes. It is almost always more useful combined with slope, elevation, lithology, and land cover than read alone.
A common confusion is between aspect and a true solar radiation model. Aspect is only the facing direction; it says nothing about how much energy actually arrives. Two slopes can share an aspect of 180 deg yet receive very different insolation if one is 5 deg steep and the other 35 deg, or if a ridge to the south casts shadow. If you need energy, use a dedicated tool — ArcGIS Area Solar Radiation, GRASS r.sun, or SAGA's potential incoming solar radiation — which integrate aspect, slope, latitude, time of year, and (for r.sun and the SAGA tool) terrain shadowing. Aspect is an input to those models, not a stand-in for them.
Reading an aspect raster
When you open a raw aspect raster, expect a value range of 0–360 plus the flat code. The fastest sanity check is to drape it over a hillshade with a cyclic ramp: each ridge should show two contrasting colours, one per flank, that flip across the crest. Valley floors and plateaux should read as the flat colour or fall out as masked. Speckle on gentle ground is the noise signature described above — it is a cue to threshold on slope before drawing conclusions. If the whole raster looks shifted by 90 or 180 degrees, suspect an axis or sign convention difference between tools (a few implementations measure counter-clockwise or from east); confirm against a slope you can verify visually, such as a known south-facing valley wall.
Common pitfalls and why they happen
- Reading flats as north. A cell coded 0 might be true north or might be a flat that the tool snapped to 0; -1 vs 0 conventions cause this. Fix: know your tool's flat convention and mask flats.
- Linear averaging or styling. Circular data through linear tools produces the "south instead of north" error and misleading maps. Use circular stats and a cyclic ramp.
- Over-interpreting noisy aspect on gentle terrain. On near-flat ground tiny elevation jitter flips aspect wildly. Threshold on slope first; only trust aspect where slope exceeds a few degrees.
- Resolution mismatch. Comparing aspect from a 30 m DEM to a 1 m DEM, or aspect to slope computed at a different cell size, mixes signals. Compute all derivatives from the same resampled DEM at one cell size.
- Edge dropout. Without
-compute_edgesthe first/last row and column become NoData, trimming your study area by one cell.
QA before you trust the output
- Confirm the DEM is true elevation (single-band float), not a hillshade or RGB render.
- Check that horizontal and vertical units are consistent (metres/metres) before computing slope; aspect direction is unit-independent but slope thresholds are not.
- Visually inspect the aspect raster with a cyclic ramp against a hillshade — ridgelines should show opposing colours on either flank.
- Verify the flat code (-1, 0, or NoData) and confirm flats are excluded from any statistic.
- For zonal summaries, validate the sin/cos circular-mean result against a hand-checked test catchment.
Bathyl perspective
We treat aspect as one band in a terrain stack rather than a standalone product: slope sets where it is trustworthy, lithology and land cover give it meaning, and the cell size is fixed across every derivative so the layers are directly comparable. Each aspect deliverable ships with its DEM source, resolution, and flat-cell convention noted, so a reviewer never has to guess whether a "north-facing" cell is real or an artefact of a flat.
Related reading
- Hillshade vs Slope
- Slope, Aspect, and Hillshade From DEM Data
- Z Factor in Hillshade and Slope Analysis
- Why Your GIS Layers Do Not Line Up
- Terrain intelligence