Landscape metrics¶
Patch, class and landscape metrics of categorical maps, their sampling in plots, windows and zones, time series, spatial signatures, plots and utilities. Tutorial: landscape metrics.
Metrics of a map¶
Landscape
¶
Landscape(
data,
*,
res=None,
nodata=None,
directions: int = 8,
count_boundary: bool = False,
consider_boundary: bool = False,
edge_depth: int = 1,
cell_center: bool = False,
classes_max: float | None = None,
neighbourhood: int = 4,
ordered: bool = True,
base: str = "log2",
band: int | None = None,
block_rows: int | str | None = None,
n_threads: int | None = None,
convention: str = "landscapemetrics",
search_radius: float | None = None,
connect_threshold: float | None = None,
contrast=None,
similarity=None,
boundary_contrast: float = 0.0,
)
Categorical raster prepared for landscape metrics.
Patches and adjacencies are computed once, on first use, and shared by
every metric. Metric names are the landscapemetrics / FRAGSTATS
abbreviations (see list_metrics()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
Categorical map: a file path, an |
required | |
res
|
Cell size |
None
|
|
nodata
|
Value treated as NA (default: the raster's nodata value). |
None
|
|
directions
|
int
|
Patch connectivity: 8 (queen's case, default) or 4 (rook's case). |
8
|
count_boundary
|
bool
|
Count the landscape boundary (and NA cells) as edge in |
False
|
consider_boundary
|
bool
|
Core-area options (cells at the boundary may be core; distance in cells from the patch edge). |
False
|
edge_depth
|
bool
|
Core-area options (cells at the boundary may be core; distance in cells from the patch edge). |
False
|
cell_center
|
bool
|
|
False
|
classes_max
|
float | None
|
Potential number of classes, for |
None
|
neighbourhood
|
int
|
Complexity metrics ( |
4
|
ordered
|
int
|
Complexity metrics ( |
4
|
base
|
int
|
Complexity metrics ( |
4
|
band
|
int | None
|
Band to read from multi-band files. |
None
|
block_rows
|
int | str | None
|
Out-of-core computation for rasters larger than memory: |
None
|
n_threads
|
int | None
|
Threads of the C++ core (default: all cores but one). |
None
|
convention
|
str
|
|
'landscapemetrics'
|
search_radius
|
float | None
|
|
None
|
connect_threshold
|
float | None
|
|
None
|
contrast
|
Edge contrast weights (0-1) between classes for |
None
|
|
boundary_contrast
|
Edge contrast weights (0-1) between classes for |
None
|
|
similarity
|
Similarity weights between classes for |
None
|
Notes
Metric names are landscapemetrics' abbreviations; FRAGSTATS abbreviations
in capitals ("SHDI") and the full names of pylandstats / FRAGSTATS
("shannon_diversity_index", "total_area") are accepted too.
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> lc = ls.Landscape(landcover)
>>> lc.n_patches
967
>>> lc.class_metrics(["ca", "np"]).head(2)
class ca np
0 1 174.500 2.0
1 2 27058.125 201.0
>>> float(lc.landscape_metrics(["shdi"])["shdi"].iloc[0])
1.8096...
>>> long = lc.metrics(type="aggregation metric") # long format, like calculate_lsm
classes
property
¶
n_patches
property
¶
patch_classes
cached
property
¶
extent
property
¶
out_of_core
property
¶
patch_metrics
¶
Patch-level metrics, one row per patch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metrics
|
Iterable[str] | str | None
|
Metric names (default: all patch metrics). Upper-case and full names are accepted; the columns keep the names as given. |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
class_metrics
¶
Class-level metrics, one row per class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metrics
|
Iterable[str] | str | None
|
Metric names (default: all class metrics). Upper-case and full names are accepted; the columns keep the names as given. |
None
|
extras
|
bool
|
With the default selection, also the metrics landscapemetrics does not
have (see |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
landscape_metrics
¶
landscape_metrics(
metrics: Iterable[str] | str | None = None, *, extras: bool = False
) -> DataFrame
Landscape-level metrics, in a single row.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metrics
|
Iterable[str] | str | None
|
As in |
None
|
extras
|
Iterable[str] | str | None
|
As in |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row, one column per metric. |
Examples:
metrics
¶
metrics(
level=None,
metric=None,
name=None,
type=None,
what=None,
*,
extras: bool = False,
full_name: bool = False,
) -> DataFrame
Selected metrics in long format, like landscapemetrics' calculate_lsm.
Selection as in [`list_metrics()`][landschaft.list_metrics] (all landscapemetrics
metrics by default; ``extras=True`` adds the FRAGSTATS ones).
``full_name=True`` adds the columns ``name``, ``type`` and
``function_name`` of each metric (as ``calculate_lsm(full_name = TRUE)``).
Returns
Returns
pandas.DataFrame
Columns ``level``, ``class``, ``id``, ``metric``, ``value``
(``class``/``id`` are missing where they do not apply). An all-NA
map gives one missing value per metric, as in landscapemetrics.
Examples:
write_metrics
¶
write_metrics(
path,
level=None,
metric=None,
name=None,
type=None,
what=None,
*,
extras: bool = False,
chunk_rows: int = 1000000,
**kwargs,
) -> Path
Write metrics() (long format) to a file, without building it in memory.
One metric at a time, the patch metrics chunk by chunk; the same rows and
types as metrics().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
|
required | |
level
|
Selection, as in |
None
|
|
metric
|
Selection, as in |
None
|
|
name
|
Selection, as in |
None
|
|
type
|
Selection, as in |
None
|
|
what
|
Selection, as in |
None
|
|
extras
|
Selection, as in |
None
|
|
chunk_rows
|
int
|
Patches per chunk. |
1000000
|
**kwargs
|
Passed to the CSV or Parquet writer. |
{}
|
Returns:
| Type | Description |
|---|---|
Path
|
The file written. |
Examples:
write_patch_metrics
¶
write_patch_metrics(
path,
metrics: Iterable[str] | str | None = None,
*,
chunk_rows: int = 1000000,
**kwargs,
) -> Path
Write patch_metrics() to a file, chunk by chunk.
The table is never built in memory: for maps with tens of millions of patches.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
|
required | |
metrics
|
Iterable[str] | str | None
|
As in |
None
|
chunk_rows
|
int
|
Patches per chunk. |
1000000
|
**kwargs
|
Passed to the CSV or Parquet writer. |
{}
|
Returns:
| Type | Description |
|---|---|
Path
|
The file written. |
Examples:
to_raster
¶
Metric painted on the map (NaN where NA): a patch-level metric on
its patches (landscapemetrics' spatialize_lsm), a class-level one
on the cells of each class.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metric
|
A metric name, or a list of them (then a dict |
required | |
level
|
str | None
|
"patch" or "class"; by default the patch level if the metric exists there, else the class level. |
None
|
path
|
Write the raster to this GeoTIFF ( |
None
|
Returns:
| Type | Description |
|---|---|
(DataArray, ndarray, dict or path)
|
The raster (same form as the input; lazy out of core), a dict of them for a list of metrics, or the path(s) written. |
Examples:
>>> import landschaft as ls
>>> lc = ls.Landscape(ls.load_raster(ls.example_data("clc")))
>>> area = lc.to_raster("area") # every patch painted with its area (ha)
>>> pland = lc.to_raster("pland", level="class")
>>> path = lc.to_raster("shape", path="shape.tif")
Out of core, written block by block:
labels
¶
Map of patch ids.
Out of core (block_rows) the map is lazy (dask): each block is read
and labelled again when computed, so it can be larger than memory;
with path it is written to the file block by block.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
path
|
Write the map to this GeoTIFF ( |
None
|
|
**write_options
|
Options of |
{}
|
Returns:
| Type | Description |
|---|---|
(DataArray, ndarray or path)
|
Patch ids 1..n (the |
Examples:
>>> import landschaft as ls
>>> lc = ls.Landscape(ls.load_raster(ls.example_data("clc")))
>>> ids = lc.labels()
>>> int(ids.max()) == lc.n_patches
True
A file read by blocks gets its map written by blocks:
patches
¶
The patches of each class, each class on a raster of its own.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
classes
|
Class values to return (default: all). |
None
|
Returns:
| Type | Description |
|---|---|
dict
|
|
Examples:
centroids
¶
Centroid of every patch, like landscapemetrics' get_centroids.
The mean of the cell-centre coordinates of the patch (map
coordinates, as terra computes them; the same bits as
landscapemetrics). With cell_center the patch cell nearest to that
point instead (several rows on ties, as landscapemetrics returns).
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
nearest_neighbours
¶
Distance from every patch to the nearest patch of its class, like
landscapemetrics' get_nearestneighbour on the patches of each class
(the distance is the enn metric: between cell centres).
With return_id, the id of the neighbour patch: one row per
neighbour when several are equally near, found with landscapemetrics'
own search (same ties). NaN / NA for classes with a single patch.
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
circumscribing_circles
¶
Smallest circle around every patch (or every class), like
landscapemetrics' get_circumscribingcircle: it encloses the corners
of the cells in the first and last rows and columns, as for the
circle metric (with convention="fragstats", every cell of the
patch).
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
adjacencies
¶
Cell adjacencies between classes, like landscapemetrics'
get_adjacencies: the number of (cell, neighbour) pairs, row = class
of the cell, column = class of the neighbour (NA cells left out).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
neighbourhood
|
4, 8, or a matrix with 1 for the neighbours and 0 for the focal cell (read transposed, as landscapemetrics does). |
4
|
|
what
|
str
|
"full" (counts), or only "like" (diagonal), "unlike" (off-diagonal)
or "triangle" (with the diagonal) of the lower triangle (upper
with |
'full'
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Class x class counts (index: class of the cell, columns: class of the neighbour). |
Examples:
boundaries
¶
boundaries(
consider_boundary: bool = False,
edge_depth: int = 1,
as_na: bool = False,
patch_id: bool = False,
)
Boundary cells of the patches.
1 for the cells within edge_depth cells (4 neighbours) of another class,
of NA or, unless consider_boundary, of the map edge; 0 inside. The
cells that are not boundary are the core cells of the core-area metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
consider_boundary
|
bool
|
Do not count the map edge as a boundary. |
False
|
edge_depth
|
int
|
Width of the boundary, in cells. |
1
|
as_na
|
bool
|
NaN instead of 0 for the inner cells. |
False
|
patch_id
|
bool
|
The patch id instead of 1 on boundary cells. |
False
|
Returns:
| Type | Description |
|---|---|
DataArray or ndarray
|
Same grid as the map, NaN where it is NA. |
Examples:
extract_metrics
¶
extract_metrics(
y,
*,
extract_id=None,
metric=None,
name=None,
type=None,
what=None,
extras: bool = False,
verbose: bool = True,
) -> DataFrame
Patch metrics of the patches under points; see extract_metrics().
Examples:
show_patches
¶
Draw the patches (needs matplotlib); see show_patches().
Examples:
show_cores
¶
Draw the core and edge cells of every class (needs matplotlib); see
show_cores().
Examples:
show_lsm
¶
Draw a patch metric on the patches (needs matplotlib); see show_lsm().
Examples:
landscape_metrics
¶
landscape_metrics(
data,
level=None,
metric=None,
name=None,
type=None,
what=None,
*,
extras: bool = False,
full_name: bool = False,
n_threads: int | None = None,
**options,
) -> DataFrame
Landscape metrics of one or several rasters, in long format.
The one-call equivalent of landscapemetrics' calculate_lsm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster (see |
required | |
level
|
Metric selection, as in |
None
|
|
metric
|
Metric selection, as in |
None
|
|
name
|
Metric selection, as in |
None
|
|
type
|
Metric selection, as in |
None
|
|
what
|
Metric selection, as in |
None
|
|
extras
|
bool
|
Also select the FRAGSTATS metrics missing in landscapemetrics
( |
False
|
full_name
|
bool
|
Add the columns |
False
|
n_threads
|
int | None
|
Threads of the C++ core (default: all cores but one). |
None
|
**options
|
|
{}
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> table = ls.landscape_metrics(landcover, level="landscape", metric=["shdi", "contag"])
>>> table[["metric", "value"]].round(2)
metric value
0 contag 69.46
1 shdi 1.81
Several rasters (a layer column numbers them):
list_metrics
¶
list_metrics(
level=None, metric=None, name=None, type=None, what=None, *, extras: bool = False
) -> DataFrame
Available landscape metrics.
Filters work as in landscapemetrics' list_lsm: level ("patch",
"class", "landscape"), metric (family, e.g. "area" selects
area, area_mn, area_sd and area_cv), name and
type (e.g. "aggregation metric") are combined, and names starting
with - exclude. what lists levels and/or function names such as
"lsm_c_ca" and overrides the other filters.
extras=True adds the metrics landscapemetrics does not have
(FRAGSTATS / pylandstats): the area-weighted mean _am, the median
_md and the range _ra of every patch metric, the statistics of
perim, and FRAGSTATS' proximity (prox), similarity (simi),
connectance (connect) and edge-contrast (econ, cwed,
teci) metrics. Extras named in what are always selected.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
"patch", "class" and/or "landscape". |
None
|
|
metric
|
Metric families, e.g. |
None
|
|
name
|
Full names or types, e.g. |
None
|
|
type
|
Full names or types, e.g. |
None
|
|
what
|
Levels and function names such as |
None
|
|
extras
|
bool
|
Include the FRAGSTATS metrics landscapemetrics does not have. |
False
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
Columns |
Examples:
Plots, windows and zones¶
sample_metrics
¶
sample_metrics(
data,
y,
*,
size: float | None = None,
shape: str = "square",
plot_id=None,
all_classes: bool = False,
level=None,
metric=None,
name=None,
type=None,
what=None,
res=None,
nodata=None,
band: int | None = None,
verbose: bool = True,
extras: bool = False,
full_name: bool = False,
return_raster: bool = False,
n_threads: int | None = None,
**options,
) -> DataFrame
Landscape metrics of sample plots, like landscapemetrics' sample_lsm.
Each plot is cut from the raster as terra::crop(mask = TRUE) does
(grid window snapped to the nearest cell edges; every cell the plot
touches is kept, the others become NA) and its metrics are computed as
a landscape of its own. All plots are computed in parallel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster (see |
required | |
y
|
Sample plots: an |
required | |
size
|
float | None
|
Buffer size around points: half the side of a square, or the radius of a circle (landscapemetrics' 100-vertex polygon). |
None
|
shape
|
str
|
|
'square'
|
plot_id
|
Identifiers of the plots (default 1..n). |
None
|
|
all_classes
|
bool
|
Add class-level rows (NA) for the classes of the whole raster that are missing in a plot (with a row for class NA when the raster has NA cells, as landscapemetrics does). |
False
|
level
|
Metric selection, as in |
None
|
|
metric
|
Metric selection, as in |
None
|
|
name
|
Metric selection, as in |
None
|
|
type
|
Metric selection, as in |
None
|
|
what
|
Metric selection, as in |
None
|
|
res
|
Raster reading options (see |
None
|
|
nodata
|
Raster reading options (see |
None
|
|
band
|
Raster reading options (see |
None
|
|
verbose
|
bool
|
Warn when a plot lies less than 90 % inside the raster. |
True
|
extras
|
bool
|
Also select the FRAGSTATS metrics missing in landscapemetrics. |
False
|
full_name
|
bool
|
Add the columns |
False
|
return_raster
|
bool
|
Add a column |
False
|
n_threads
|
int | None
|
Threads of the C++ core (default: all cores but one). |
None
|
**options
|
Metric options ( |
{}
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> import numpy as np
>>> xmin, xmax, ymin, ymax = ls.Landscape(landcover).extent
>>> points = np.array([[xmin + 5000, ymin + 5000], [xmax - 5000, ymax - 5000]])
>>> plots = ls.sample_metrics(landcover, points, size=1000, shape="circle",
... level="landscape", metric=["shdi", "np"])
>>> plots["plot_id"].unique().tolist()
[1, 2]
scale_sample
¶
scale_sample(
data,
y,
*,
size,
shape: str = "square",
level=None,
metric=None,
name=None,
type=None,
what=None,
verbose: bool = True,
full_name: bool = False,
**options,
) -> DataFrame
Landscape metrics of buffers of several sizes around points, like
landscapemetrics' scale_sample.
sample_metrics() for each buffer size in size (the plots of all
sizes are computed in parallel). y: an (n, 2) array of
coordinates or point geometries; other arguments (full_name too) as
in sample_metrics().
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> import numpy as np
>>> xmin, xmax, ymin, ymax = ls.Landscape(landcover).extent
>>> points = np.array([[xmin + 5000, ymin + 5000], [xmax - 5000, ymax - 5000]])
>>> scales = ls.scale_sample(landcover, points, size=[500, 1000, 2000], what=["lsm_l_shdi"])
>>> sorted(scales["size"].unique().tolist())
[500.0, 1000.0, 2000.0]
extract_metrics
¶
extract_metrics(
data,
y,
*,
extract_id=None,
metric=None,
name=None,
type=None,
what=None,
extras: bool = False,
full_name: bool = False,
verbose: bool = True,
n_threads: int | None = None,
**options,
) -> DataFrame
Patch metrics of the patches under points, like landscapemetrics'
extract_lsm.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster (see |
required | |
y
|
Points: an |
required | |
extract_id
|
Identifiers of the points (default 1..n). |
None
|
|
metric
|
Selection of patch-level metrics, as in
|
None
|
|
name
|
Selection of patch-level metrics, as in
|
None
|
|
type
|
Selection of patch-level metrics, as in
|
None
|
|
what
|
Selection of patch-level metrics, as in
|
None
|
|
extras
|
Selection of patch-level metrics, as in
|
None
|
|
full_name
|
bool
|
Add the columns |
False
|
**options
|
|
{}
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> import numpy as np
>>> xmin, xmax, ymin, ymax = ls.Landscape(landcover).extent
>>> points = np.array([[xmin + 5000, ymin + 5000], [xmax - 5000, ymax - 5000]])
>>> table = ls.extract_metrics(landcover, points, what=["lsm_p_area", "lsm_p_shape"])
>>> sorted(table["metric"].astype(str).unique())
['area', 'shape']
window_metrics
¶
window_metrics(
data,
window,
level="landscape",
metric=None,
name=None,
type=None,
what=None,
*,
res=None,
nodata=None,
band: int | None = None,
extras: bool = False,
n_threads: int | None = None,
**options,
)
Landscape-level metrics in a moving window, like landscapemetrics'
window_lsm.
For every cell, the cells of the window centred on it form a landscape (cells outside the raster or outside the window shape are NA), and its metrics become the cell's values. Windows are computed in parallel.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster (see |
required | |
window
|
Odd side of a square window, or a 2-D array with odd sides whose cells that are True / non-zero (and not NaN) form the window, e.g. a circle. |
required | |
level
|
Metric selection, as in |
'landscape'
|
|
metric
|
Metric selection, as in |
'landscape'
|
|
name
|
Metric selection, as in |
'landscape'
|
|
type
|
Metric selection, as in |
'landscape'
|
|
what
|
Metric selection, as in |
'landscape'
|
|
res
|
Raster reading options (see |
None
|
|
nodata
|
Raster reading options (see |
None
|
|
band
|
Raster reading options (see |
None
|
|
extras
|
bool
|
Also select the FRAGSTATS metrics missing in landscapemetrics. |
False
|
n_threads
|
int | None
|
Threads of the C++ core (default: all cores but one). |
None
|
**options
|
Metric options ( |
{}
|
Returns:
| Type | Description |
|---|---|
dict
|
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> maps = ls.window_metrics(landcover[:300, :300], window=21, what=["lsm_l_shdi", "lsm_l_ed"])
>>> sorted(maps)
['ed', 'shdi']
A circular window:
zonal_metrics
¶
zonal_metrics(
data,
zones,
level="landscape",
metric=None,
name=None,
type=None,
what=None,
*,
extras: bool = False,
separator: str = "_",
**options,
)
Landscape and class metrics of every zone, as a GeoDataFrame.
The zones are cut out of the raster as in sample_metrics() (same
values), and the results come back in wide form next to the zones'
geometry and attributes: one row per zone, one column per landscape-level
metric and one per class-level metric and class (<metric>_<class>),
plus percentage_inside. Write it with write_table() or
.to_file("zones.gpkg").
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
One raster (see |
required | |
zones
|
Polygons: a GeoDataFrame / GeoSeries (attributes and CRS are kept), shapely polygons or GeoJSON-like geometries, in the raster's coordinates. |
required | |
level
|
Metric selection (class and landscape level), as in
|
'landscape'
|
|
metric
|
Metric selection (class and landscape level), as in
|
'landscape'
|
|
name
|
Metric selection (class and landscape level), as in
|
'landscape'
|
|
type
|
Metric selection (class and landscape level), as in
|
'landscape'
|
|
what
|
Metric selection (class and landscape level), as in
|
'landscape'
|
|
extras
|
Metric selection (class and landscape level), as in
|
'landscape'
|
|
separator
|
str
|
Between metric and class in the class-level column names. |
'_'
|
**options
|
|
{}
|
Returns:
| Type | Description |
|---|---|
GeoDataFrame
|
|
Examples:
grid_zones
¶
Square zones tiling a raster, for zonal analyses.
Squares of side size from the top-left corner of the raster (partial
squares at the right and bottom edges), in row-major order.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
The raster (path, DataArray or array). |
required | |
size
|
Side of the squares, in map units. |
required | |
res
|
Reading options, as in |
None
|
|
nodata
|
Reading options, as in |
None
|
|
band
|
Reading options, as in |
None
|
Returns:
| Type | Description |
|---|---|
list of dict
|
GeoJSON-like polygons, accepted by |
Examples:
Metric tables (and zonal metrics as GeoDataFrames) are written with
ls.write_table or ls.save.
Time series and spatial signatures¶
SpatioTemporalAnalysis
¶
SpatioTemporalAnalysis(
rasters,
dates=None,
*,
zones=None,
points=None,
size=None,
shape: str = "square",
grid=None,
**options,
)
Landscape metrics along a time series of rasters (pylandstats'
SpatioTemporalAnalysis and its zonal, buffer and grid variants).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rasters
|
The rasters (paths, DataArrays, arrays) or a
|
required | |
dates
|
Labels of the rasters (default 1..n). |
None
|
|
zones
|
Polygons to analyse separately (as in |
None
|
|
points
|
Buffers of |
None
|
|
size
|
Buffers of |
None
|
|
shape
|
Buffers of |
None
|
|
grid
|
Side of square zones tiling the rasters instead of zones. |
None
|
|
**options
|
Metric options ( |
{}
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> import numpy as np
>>> later = landcover.copy()
>>> later.values[:500, :500] = np.where(later.values[:500, :500] == 12, 1, later.values[:500, :500])
>>> series = ls.SpatioTemporalAnalysis([landcover, later], dates=[2018, 2030])
>>> series.landscape_metrics(["np", "shdi"]).columns.tolist() # indexed by date
['np', 'shdi']
metrics
¶
metrics(
level=None, metric=None, name=None, type=None, what=None, *, extras: bool = False
) -> DataFrame
Selected metrics of every date, in long format.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
level
|
Selection, as in |
None
|
|
metric
|
Selection, as in |
None
|
|
name
|
Selection, as in |
None
|
|
type
|
Selection, as in |
None
|
|
what
|
Selection, as in |
None
|
|
extras
|
Selection, as in |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
The long table of |
Examples:
landscape_metrics
¶
Landscape-level metrics, one row per date (and zone).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metrics
|
Metric names (default: all landscape metrics). |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One column per metric, indexed by |
Examples:
class_metrics
¶
Class-level metrics, one row per class and date (and zone).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metrics
|
Metric names (default: all class metrics). |
None
|
|
classes
|
Class values to keep (default: all). |
None
|
|
fillna
|
bool
|
A class absent at a date gets 0 for area, edge and count metrics
( |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One column per metric, indexed by |
Examples:
plot_metric
¶
Line plot of a metric over the dates (needs matplotlib).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metric
|
str
|
A landscape or class metric. |
required |
classes
|
|
None
|
|
ax
|
A matplotlib axes to draw in. |
None
|
|
**plot_kwargs
|
Passed to matplotlib's |
{}
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
SpatialSignatureAnalysis
¶
SpatialSignatureAnalysis(
rasters=None,
*,
landscape_metrics=None,
class_metrics=None,
classes=None,
fillna: bool = True,
zones=None,
points=None,
size=None,
shape: str = "square",
grid=None,
table: DataFrame = None,
**options,
)
Landscapes (or zones) described by their metrics: the "spatial
signature" matrix, its principal components and clusters (pylandstats'
SpatialSignatureAnalysis).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
rasters
|
Rasters (or a |
None
|
|
landscape_metrics
|
Metric names; class metrics become one column per class
( |
None
|
|
class_metrics
|
Metric names; class metrics become one column per class
( |
None
|
|
fillna
|
bool
|
0 instead of NaN for area / edge / count class metrics of absent classes. |
True
|
zones
|
Zonal signatures of one raster (see |
None
|
|
points
|
Zonal signatures of one raster (see |
None
|
|
size
|
Zonal signatures of one raster (see |
None
|
|
shape
|
Zonal signatures of one raster (see |
None
|
|
grid
|
Zonal signatures of one raster (see |
None
|
|
**options
|
Metric options. |
{}
|
Examples:
>>> import landschaft as ls
>>> landcover = ls.load_raster(ls.example_data("clc"))
>>> signatures = ls.SpatialSignatureAnalysis(landcover, grid=5000, landscape_metrics=["shdi", "ed", "np"],
... class_metrics=["pland"])
>>> signatures.table.shape
(100, 29)
>>> groups = signatures.cluster(4)
from_table
classmethod
¶
from_table(table: DataFrame) -> SpatialSignatureAnalysis
An analysis of a ready signature matrix.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
table
|
DataFrame
|
Rows = landscapes or zones, columns = metrics. |
required |
Returns:
| Type | Description |
|---|---|
SpatialSignatureAnalysis
|
|
Examples:
pca
¶
pca(n_components: int | None = None) -> PCAResult
Principal components of the standardised metrics.
The metrics are turned into z-scores; constant metrics are left out. Signs as scikit-learn's PCA (the largest loading of each component is positive).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_components
|
int | None
|
Components to keep (default: all). |
None
|
Returns:
| Type | Description |
|---|---|
PCAResult
|
Scores, loadings and explained variance ratios. |
Examples:
nmf
¶
nmf(n_components: int, *, max_iter: int = 1000, tol: float = 1e-06) -> NMFResult
Non-negative matrix factorisation of the metrics.
Each metric is scaled to [0, 1] (constant metrics left out); scores (W)
times components (H) approximates them, both non-negative, with the
Frobenius loss (NNDSVDa start, HALS updates, as scikit-learn's
NMF(init="nndsvda", solver="cd")). Deterministic.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_components
|
int
|
Number of factors. |
required |
max_iter
|
int
|
Maximum number of sweeps. |
1000
|
tol
|
float
|
Stop when the loss improves by less than this (relative). |
1e-06
|
Returns:
| Type | Description |
|---|---|
NMFResult
|
|
Examples:
cluster
¶
cluster(
n_clusters: int,
*,
method: str = "kmeans",
n_components: int | None = None,
n_init: int = 10,
seed: int = 0,
) -> Series
Groups of landscapes (or zones) with similar metrics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_clusters
|
int
|
Number of groups. |
required |
method
|
str
|
|
'kmeans'
|
n_components
|
int | None
|
Cluster the first principal components instead of all metrics. |
None
|
n_init
|
int
|
k-means restarts and random seed. |
10
|
seed
|
int
|
k-means restarts and random seed. |
10
|
Returns:
| Type | Description |
|---|---|
Series
|
The group of every row, numbered 0..k-1 in order of first appearance. |
Examples:
clustergram
¶
clustergram(
k_range=range(1, 9),
*,
method: str = "kmeans",
n_components: int | None = None,
pca_weighted: bool = True,
n_init: int = 10,
seed: int = 0,
) -> ClustergramResult
Clusters for a range of k, for a clustergram.
For every k in k_range, the cluster of every row and the mean of its
cluster (the centre projected on the first principal axis, or averaged over
the columns).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
k_range
|
Numbers of clusters. |
range(1, 9)
|
|
method
|
str
|
As in |
'kmeans'
|
n_components
|
str
|
As in |
'kmeans'
|
n_init
|
str
|
As in |
'kmeans'
|
seed
|
str
|
As in |
'kmeans'
|
pca_weighted
|
bool
|
Project the cluster means on the first principal axis. |
True
|
Returns:
| Type | Description |
|---|---|
ClustergramResult
|
|
Examples:
plot_clustergram
¶
plot_clustergram(
result: ClustergramResult | None = None,
*,
ax=None,
size: float = 1.0,
linewidth: float = 1.0,
**kwargs,
)
Draw a clustergram (needs matplotlib).
For every k, a dot per cluster at its mean, sized by its rows, and lines between the clusters of k and k + 1 as wide as the rows they share.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
result
|
ClustergramResult | None
|
A |
None
|
ax
|
A matplotlib axes to draw in. |
None
|
|
size
|
float
|
Scale of the dots and lines. |
1.0
|
linewidth
|
float
|
Scale of the dots and lines. |
1.0
|
**kwargs
|
Passed to |
{}
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
plot_pca
¶
Scatter plot of two principal components, with the metric loadings as arrows.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
clusters
|
Series | None
|
Colour the points by these groups (e.g. from |
None
|
components
|
The two components to draw (1-based). |
(1, 2)
|
|
ax
|
A matplotlib axes to draw in. |
None
|
|
labels
|
bool
|
Write the row labels. |
False
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
plot_cluster_metrics
¶
Box plots of every metric per cluster.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
clusters
|
Series
|
Groups of the rows, e.g. from |
required |
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
PCAResult
dataclass
¶
PCAResult(
scores: DataFrame,
loadings: DataFrame,
explained_variance_ratio: ndarray,
dropped: list,
)
Bases: Saveable
Principal components of the spatial signatures.
NMFResult
dataclass
¶
NMFResult(
scores: DataFrame,
components: DataFrame,
reconstruction_error: float,
n_iter: int,
dropped: list,
)
Bases: Saveable
Non-negative factors of the spatial signatures (min-max scaled metrics ~ scores @ components.T).
ClustergramResult
dataclass
¶
Bases: Saveable
Clusters for a range of k (Schonlau's clustergram, as the clustergram
package that pylandstats' get_cgram uses).
Plots¶
show_patches
¶
show_patches(
landscape,
classes="global",
*,
labels: bool = False,
cmap="tab20",
ncols=None,
nrows=None,
**options,
)
Map of the patches, each in its own colour (landscapemetrics'
show_patches).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
landscape
|
required | ||
classes
|
"global" (all patches on one map), "all" (one map per class) or class value(s). |
'global'
|
|
labels
|
bool
|
Write the patch ids at the patch centroids. |
False
|
cmap
|
Colour map (cycled over patch ids) and panel layout. |
'tab20'
|
|
ncols
|
Colour map (cycled over patch ids) and panel layout. |
'tab20'
|
|
nrows
|
Colour map (cycled over patch ids) and panel layout. |
'tab20'
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
show_cores
¶
show_cores(
landscape,
classes="all",
*,
edge_depth: int = 1,
consider_boundary: bool = True,
labels: bool = False,
ncols=None,
nrows=None,
**options,
)
Core and edge cells of the patches (landscapemetrics' show_cores):
core cells dark, edge cells light, other classes blank.
edge_depth and consider_boundary as for the core-area metrics
(landscapemetrics' plot defaults: consider_boundary=True);
labels writes the core area (ha) of each patch.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
landscape
|
required | ||
classes
|
"all" (one panel per class, default), "global" or class value(s). |
'all'
|
|
edge_depth
|
int
|
As for the core-area metrics. |
1
|
consider_boundary
|
int
|
As for the core-area metrics. |
1
|
labels
|
bool
|
Write the core area (ha) of each patch. |
False
|
ncols
|
Panel layout. |
None
|
|
nrows
|
Panel layout. |
None
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
show_lsm
¶
show_lsm(
landscape,
metric: str,
classes="global",
*,
labels: bool = False,
cmap="viridis",
ncols=None,
nrows=None,
**options,
)
A patch-level metric painted on the patches (landscapemetrics'
show_lsm), with a colour bar; labels writes the values.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
landscape
|
required | ||
metric
|
str
|
A patch-level metric. |
required |
classes
|
"global" (one map, default), "all" or class value(s). |
'global'
|
|
labels
|
bool
|
Write the values on the patches. |
False
|
cmap
|
Colour map and panel layout. |
'viridis'
|
|
ncols
|
Colour map and panel layout. |
'viridis'
|
|
nrows
|
Colour map and panel layout. |
'viridis'
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
show_correlation
¶
show_correlation(
data,
method: str = "pearson",
*,
diag: bool = True,
labels: bool = False,
cmap="RdBu_r",
)
Heatmap of the correlations between metrics (landscapemetrics'
show_correlation), one panel per level.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A long table of metrics (correlated with
|
required | |
labels
|
bool
|
Write the correlation values in the cells. |
False
|
Returns:
| Type | Description |
|---|---|
Figure
|
|
Examples:
Utilities¶
check_landscape
¶
Is a raster suitable for landscape metrics? Like landscapemetrics'
check_landscape.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster or a list of rasters. |
required | |
verbose
|
bool
|
Warn about the problems found. |
True
|
nodata
|
Reading options, as in |
None
|
|
band
|
Reading options, as in |
None
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
One row per raster: |
Examples:
calculate_correlation
¶
calculate_correlation(
metrics: DataFrame,
method: str = "pearson",
diag: bool = True,
simplify: bool = False,
)
Correlation between metrics, like landscapemetrics' calculate_correlation.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
metrics
|
DataFrame
|
A long table of metrics ( |
required |
method
|
str
|
"pearson", "spearman" or "kendall" (R's |
'pearson'
|
diag
|
bool
|
Keep the diagonal (correlation 1). |
True
|
simplify
|
bool
|
Return the table itself when a single level is present. |
False
|
Returns:
| Type | Description |
|---|---|
dict or DataFrame
|
|
Examples:
raster_boundaries
¶
raster_boundaries(
data,
*,
consider_boundary: bool = False,
edge_depth: int = 1,
as_na: bool = False,
patch_id: bool = False,
nodata=None,
band: int | None = None,
n_threads: int | None = None,
)
landscapemetrics' get_boundaries on the values of a raster.
The values are taken as they are (classes, or patch ids such as
labels() or patches()). A cell is a
boundary cell as in landscapemetrics' rcpp_get_boundaries: the cell
below holds another value or NA, or the cell above, left or right is NA;
the map edge counts as NA unless consider_boundary. As in
landscapemetrics, patch_id is ignored (with a warning) when a value
is 0. (On a map of
several classes this marks only one side of a class change;
boundaries() gives the boundaries of the patches of every
class.) edge_depth > 1 peels the boundary off and repeats.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster of classes or patch ids. |
required | |
consider_boundary
|
bool
|
Do not count the map edge as NA. |
False
|
edge_depth
|
int
|
Width of the boundary, in cells. |
1
|
as_na
|
bool
|
NaN instead of 0 for the inner cells. |
False
|
patch_id
|
bool
|
The cell value instead of 1 on boundary cells. |
False
|
nodata
|
Reading options. |
None
|
|
band
|
Reading options. |
None
|
|
n_threads
|
int | None
|
Threads ( |
None
|
Returns:
| Type | Description |
|---|---|
DataArray or ndarray
|
1 on boundary cells (their value with |
Examples:
construct_buffer
¶
Square or circular sample plots around points, like landscapemetrics'
construct_buffer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
coords
|
Points: an |
required | |
shape
|
str
|
|
required |
size
|
float
|
Buffer size, in map units. |
required |
return_vec
|
bool
|
True: a |
True
|
crs
|
CRS of the polygons ( |
None
|
Notes
These are the plots sample_metrics() builds around points.
Examples:
pad_raster
¶
pad_raster(
data,
pad_raster_value: float = -999,
pad_raster_cells: int = 1,
global_: bool = False,
return_raster: bool = True,
*,
nodata=None,
band: int | None = None,
)
Add rows and columns of pad_raster_value around a raster, like
landscapemetrics' pad_raster.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster (file, DataArray, numpy or masked array) or a list of them. |
required | |
pad_raster_value
|
float
|
Value of the new cells. |
-999
|
pad_raster_cells
|
int
|
Number of rows / columns added on each side. |
1
|
global_
|
bool
|
Also replace the NA cells by |
False
|
return_raster
|
bool
|
Return a georeferenced raster (DataArray, NaN = NA, extent grown by the new cells) for georeferenced inputs; numpy input always gives a numpy array. |
True
|
nodata
|
Reading options, as in |
None
|
|
band
|
Reading options, as in |
None
|
Returns:
| Type | Description |
|---|---|
xarray.DataArray or numpy.ndarray (float), or a list for several rasters.
|
|
Examples:
unpad_raster
¶
unpad_raster(
data,
unpad_raster_cells: int = 1,
return_raster: bool = True,
*,
nodata=None,
band: int | None = None,
)
Remove unpad_raster_cells rows and columns on each side of a
raster, like landscapemetrics' unpad_raster (the inverse of
pad_raster()). Arguments and result as in pad_raster().
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster or a list of rasters. |
required | |
unpad_raster_cells
|
int
|
Rows and columns removed on each side. |
1
|
return_raster
|
bool
|
Return a georeferenced DataArray for georeferenced input. |
True
|
nodata
|
Reading options. |
None
|
|
band
|
Reading options. |
None
|
Returns:
| Type | Description |
|---|---|
xarray.DataArray or numpy.ndarray (float), or a list for several rasters.
|
|
Examples:
raster_to_points
¶
raster_to_points(
data, return_NA: bool = True, *, nodata=None, band: int | None = None
) -> DataFrame
Cell centres and values, like landscapemetrics' raster_to_points.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster or a list of rasters (see |
required | |
return_NA
|
bool
|
Keep the NA cells (value NaN). |
True
|
Returns:
| Type | Description |
|---|---|
DataFrame
|
|
Examples:
get_unique_values
¶
The distinct values of rasters (NA left out, doubles truncated to
integers), sorted, like landscapemetrics' get_unique_values.
data: a raster (file, DataArray, numpy array of any dimension up to 2,
masked array) or a list of them. Returns {"layer_1": values, ...}
as landscapemetrics does, or only the values of a single raster with
simplify=True.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
data
|
A raster (file, DataArray, numpy or masked array, also 1-D) or a list of them. |
required | |
simplify
|
bool
|
Return the values of a single raster directly. |
False
|
nodata
|
Reading options. |
None
|
|
band
|
Reading options. |
None
|
Returns:
| Type | Description |
|---|---|
dict or ndarray
|
|
Examples: