map_dens() creates a smoothed utilisation distribution (UD).
Usage
as.im.SpatRaster(.map)
as.owin.SpatRaster(.map, .im = NULL)
as.owin.sf(.poly, .bbox = sf::st_bbox(.poly), .invert = TRUE)
bw.h(X)
map_dens(
.map,
.owin = as.owin.SpatRaster(.map),
.coord = NULL,
.discretise = FALSE,
.shortcut = list(),
.sigma = bw.h,
...,
.fterra = FALSE,
.plot = TRUE,
.tryCatch = TRUE,
.verbose = getOption("patter.verbose")
)Arguments
- .map
A
terra::SpatRasterthat defines the grid on which the UD is represented. If.coord = NULL,.mapalso defines the points (and associated weights) that are smoothed (see.map_coord()). The coordinate reference system of.mapmust be planar and specified.- .im, .owin
A pixel image representation of
.map(seeas.im.SpatRaster()andspatstat.geom::im()) and an observation window (seeas.owin.SpatRaster(),as.owin.sf()andspatstat.geom::owin()). If un-supplied,.owinis defined automatically from.mapviaas.owin.SpatRaster(), which usesas.im.SpatRaster()internally (see Details). For faster results, use a rectangular or polygon observation window (seeas.owin.sf()).- .poly, .bbox, .invert
For
as.owin.sf()to construct observation windows fromsfobjects..polyis ansfpolygon object;.bboxis the bounding of a simple feature (seesf::st_bbox());.invertis a logical variable that defines whether or not to invert.poly(e.g., to turn a terrestrial polygon into an aquatic polygon);
- .coord
(optional) Coordinates for density estimation, provided in any format accepted by
.map_coord(). Coordinates must be planar.- .discretise
If
.coordis provided,.discretiseis alogicalvariable that defines whether or not to discretise coordinates on.map(see.map_coord()).- .shortcut
(optional) A named
listfrom a previous call tomap_dens(). If supplied, the function short-cuts straight to smoothing (.owin,.coordand.discretiseare silently unused).- .sigma, X
.sigmais anumericvalue or afunctionthat specifies the smoothing bandwidth (passed tospatstat.explore::density.ppp()'ssigmaargument). The default option isbw.h(), which sets the bandwidth based on combined variance of summarised coordinates, formatted as a point patternX(seespatstat.geom::ppp), using the ad-hoc method (Worton, 1989). Seespatstatfunctions (e.g.,spatstat.explore::bw.diggle()) for more sophisticated methods.- ...
Arguments for density estimation, passed to
spatstat.explore::density.ppp(), such assigma(i.e., the bandwidth).atandseare not permitted.- .fterra
A
logicalvariable that defines whether or not to paralleliseterra::resample().- .plot
A
logicalvariable that defines whether or not to plot the output.- .tryCatch
A
logicalvariable that controls error handling:If
.tryCatch = FALSE, if density estimation fails with an error, the function fails with the same error.If
.tryCatch = TRUE, if density estimation fails with an error, the function produces a warning with the error message and returnsNULL.
- .verbose
User output control (see
patter-progressfor supported options).
Value
The function returns a named list, with the following elements:
x: aspatstat.geom::pppobject that defines points for density estimation;D: aspatstat.geom::imobject of estimated intensities, fromspatstat.explore::density.ppp();ud: a normalisedterra::SpatRaster;
D and ud are NULL if spatstat.explore::density.ppp() fails and .tryCatch = TRUE.
Details
map_dens() smooths (a) a terra::SpatRaster or (b) a set of inputted coordinates.
.map_coord() (and .map_mark()) are used to define coordinates and weights:
If
.coordsisNULL,.mapcell coordinates are used for density estimation and cell values are used as weights.If coordinates are supplied, coordinates are optionally re-expressed on
.mapand then used for density estimation. This option is generally faster. Coordinate weights are defined by.map_mark().
Cell coordinates and associated weights are converted to a spatstat.geom::ppp() object, which is passed, alongside the observation window (.owin), to spatstat.explore::density.ppp() for the estimation. Weights must sum to one.
as.im.SpatRaster(), as.owin.SpatRaster() and as.owin.sf() are helper functions that convert a terra::SpatRaster to a pixel image and an observation window (see spatstat.geom::owin()). as.im.SpatRaster() is based on maptools::as.im.RasterLayer(). as.owin.SpatRaster() either defines a rectangular window, if there are no NAs on .map, or converts .map directly to an owin object. Gridded observation windows, especially if high resolution, considerably slow down density estimation and may exhaust vector memory. Use rectangular windows, or convert sf objects to polygon windows (via as.owin.sf()) if possible.
If .shortcut is supplied, the preceding steps can be skipped and the function short-cuts straight to smoothing. Use this option if the preceding steps are slow and you want to trial different smoothing options (such as sigma functions).
Coordinates and associated weights are smoothed via spatstat.explore::density.ppp() into an image. Pixel resolution and smoothing parameters such as bandwidth can be controlled via ... arguments which are passed directly to this function. The default bandwidth is set via bw.h() (see .sigma). The output is translated into a gridded probability density surface (on the geometry defined by .map). This process may use terra::resample(), which can be parallelised via .fterra (which controls the threads argument of that function).
This function replaces flapper::kud*() and flapper::pf_kud*() routines based on adehabitatHR (see here).
On Linux, these functions cannot be used within a Julia session.
References
Worton, B. J. (1989). Kernel Methods for Estimating the Utilization Distribution in Home-Range Studies. Ecology 70, 164–168. doi: 10.2307/1938423
See also
map_*() functions build maps of space use:
map_pou()maps probability-of-use;map_dens()maps point density;map_hr_*()functions map home ranges;
All maps are represented as terra::SpatRasters.
To derive coordinates for mapping patterns of space use for tagged animals, see:
coa()to calculate centre-of-activity;pf_filter()and associates to sample locations using particle filtering;
Examples
if (patter_run(.julia = FALSE, .geospatial = TRUE)) {
library(data.table)
library(dtplyr)
library(dplyr, warn.conflicts = FALSE)
library(spatstat.explore)
#### Define map
map <- dat_gebco()
#### Example (1): Use sample coordinates
# Sample example coordinates
coord <-
map |>
terra::spatSample(size = 100L, xy = TRUE, cell = TRUE, na.rm = TRUE) |>
select("x", "y") |>
as.data.table()
# Use x, y coordinates
map_dens(map, .coord = coord)
# Other formats are acceptable
map_dens(map, .coord = as.matrix(coord))
map_dens(map, .coord = as.data.frame(coord))
# `cell_x` and `cell_y` coordinates are acceptable
map_dens(map, .coord = coord[, .(cell_x = x, cell_y = y)])
# A SpatRaster is also acceptable
pou <- map_pou(map, .coord = coord, .plot = FALSE)$ud
map_dens(pou)
#### Example (2): Use coordinates from `sim_path_walk()`
coord <- dat_path()
map_dens(map, .coord = coord)
points(coord$x, coord$y, cex = 0.5)
#### Example (3): Use coordinates from `coa()`
# Use example dataset
coord <- dat_coa()
map_dens(map, .coord = coord)
points(coord$x, coord$y, cex = 0.5)
#### Example (4): Use a time series of coordinates from `pf_*()`
# Use example dataset
# * We use particles from the forward filter (`?pf_filter()`);
# * Particles are equally weighted b/c re-sampling is implemented every time step;
# * It is better to use outputs from the particle smoother;
coord <- dat_pff()$states
map_dens(map, .coord = coord)
# points(coord$x, coord$y, cex = 0.5)
#### Example (5): Control smoothing via `spatstat.explore::density.ppp()`
# E.g. use fixed bandwidth:
map_dens(map, .coord = coord, .sigma = 5)
map_dens(map, .coord = coord, .sigma = 100)
# E.g., perform automatic bandwidth selection using cross validation:
if (FALSE) {
# These examples are slow
map_dens(map, .coord = coord, .sigma = bw.diggle) # 2 s
map_dens(map, .coord = coord, .sigma = bw.scott) # 1 s
map_dens(map, .coord = coord, .sigma = bw.ppl) # 65 s
map_dens(map, .coord = coord, .sigma = bw.CvL) # 25 s
}
}
#> Loading required package: spatstat.data
#> Loading required package: spatstat.univar
#> spatstat.univar 3.1-2
#> Loading required package: spatstat.geom
#> spatstat.geom 3.3-6
#>
#> Attaching package: ‘spatstat.geom’
#> The following object is masked from ‘package:data.table’:
#>
#> shift
#> Loading required package: spatstat.random
#> spatstat.random 3.3-3
#> Loading required package: nlme
#>
#> Attaching package: ‘nlme’
#> The following object is masked from ‘package:dplyr’:
#>
#> collapse
#> spatstat.explore 3.4-2
#> `patter::map_dens()` called @ 2025-04-22 09:30:56...
#> ... 09:30:56: Processing `.map`...
#> ... 09:30:56: Building XYM...
#> ... 09:30:56: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:56: Estimating density surface...
#> ... 09:30:56: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:56 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:56...
#> ... 09:30:56: Processing `.map`...
#> ... 09:30:56: Building XYM...
#> ... 09:30:56: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:56: Estimating density surface...
#> ... 09:30:56: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:56 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:56...
#> ... 09:30:56: Processing `.map`...
#> ... 09:30:56: Building XYM...
#> ... 09:30:56: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:56: Estimating density surface...
#> ... 09:30:56: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:57 (duration: ~1 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:57...
#> ... 09:30:57: Processing `.map`...
#> ... 09:30:57: Building XYM...
#> ... 09:30:57: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:57: Estimating density surface...
#> ... 09:30:57: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:57 (duration: ~0 sec(s)).
#> `patter::map_pou()` called @ 2025-04-22 09:30:57...
#> ... Building XYM...
#> ... Building SpatRaster...
#> `patter::map_pou()` call ended @ 2025-04-22 09:30:57 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:57...
#> ... 09:30:57: Processing `.map`...
#> ... 09:30:57: Building XYM...
#> ... 09:30:57: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:57: Estimating density surface...
#> ... 09:30:57: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:57 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:57...
#> ... 09:30:57: Processing `.map`...
#> ... 09:30:57: Building XYM...
#> ... 09:30:57: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:57: Estimating density surface...
#> ... 09:30:57: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:57 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:57...
#> ... 09:30:57: Processing `.map`...
#> ... 09:30:57: Building XYM...
#> ... 09:30:57: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:57: Estimating density surface...
#> ... 09:30:57: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:57 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:57...
#> ... 09:30:57: Processing `.map`...
#> ... 09:30:57: Building XYM...
#> ... 09:30:57: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:57: Estimating density surface...
#> ... 09:30:57: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:57 (duration: ~0 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:57...
#> ... 09:30:57: Processing `.map`...
#> ... 09:30:57: Building XYM...
#> ... 09:30:58: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:58: Estimating density surface...
#> ... 09:30:58: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:58 (duration: ~1 sec(s)).
#> `patter::map_dens()` called @ 2025-04-22 09:30:58...
#> ... 09:30:58: Processing `.map`...
#> ... 09:30:58: Building XYM...
#> ... 09:30:58: Defining `ppp` object...
#> Observation window is gridded.
#> ... 09:30:58: Estimating density surface...
#> ... 09:30:58: Scaling density surface...
#> `patter::map_dens()` call ended @ 2025-04-22 09:30:58 (duration: ~0 sec(s)).
