Title: | Coloring Wildlife Distributions in Space-Time |
---|---|
Description: | Color and visualize wildlife distributions in space-time using raster data. In addition to enabling display of sequential change in distributions through the use of small multiples, 'colorist' provides functions for extracting several features of interest from a sequence of distributions and for visualizing those features using HCL (hue-chroma-luminance) color palettes. Resulting maps allow for "fair" visual comparison of intensity values (e.g., occurrence, abundance, or density) across space and time and can be used to address questions about where, when, and how consistently a species, group, or individual is likely to be found. |
Authors: | Justin Schuetz [aut] , Matthew Strimas-Mackey [aut, cre] , Tom Auer [aut] |
Maintainer: | Matthew Strimas-Mackey <[email protected]> |
License: | GPL-3 |
Version: | 0.1.3 |
Built: | 2024-10-26 04:26:41 UTC |
Source: | https://github.com/mstrimas/colorist |
A RasterStack of utilization distributions for two
individual African Elephants in Etosha National Park in 2011. Cell values
represent the probability density that an elephant was found at a given
location within the year and the two layers contain data for the two
individual elephants. Utilization distributions were generated using the
adehabitatHR
package from GPS tracking data. W. Kilian, W.M. Getz, R.
Zidon, and M. Tsalyuk graciously provided permission to use their data for
visualization purposes.
elephant_ud
elephant_ud
An object of class RasterStack
of dimension 208 x 193 x 2.
https://datarepository.movebank.org/handle/10255/move.812
Tsalyuk, M., W. Kilian, B. Reineking, W. Marcus. 2018. Temporal variation in resource selection of African elephants follows long term variability in resource availability. Ecological Monographs. doi:10.1002/ecm.1348
Kilian, W., W.M. Getz, R. Zidon, M. Tsalyuk. 2018. Data from: Temporal variation in resource selection of African elephants follows long term variability in resource availability. Movebank Data Repository. doi:10.5441/001/1.3nj3qj45
A RasterStack of the expected probability of occurrence of Field Sparrow from the eBird Status & Trends project. Each of the 12 layers in the stack represent the estimated occurrence for a given month of the year over a regular grid of points covering the full range of the species. To reduce file size, these data have been aggregated from the native 3 km spatial resolution and weekly temporal resolution to monthly, 27 km resolution.
fiespa_occ
fiespa_occ
An object of class RasterStack
of dimension 100 x 121 x 12.
For further details on these data, and to access the data for more species,
consult the documentation for the ebirdst
package.
https://ebird.org/science/status-and-trends
Fink, D., T. Auer, A. Johnston, M. Strimas-Mackey, S. Ligocki, O. Robinson, W. Hochachka, L. Jaromczyk, C. Crowley, K. Dunham, A. Stillman, I. Davies, A. Rodewald, V. Ruiz-Gutierrez, C. Wood. 2023. eBird Status and Trends, Data Version: 2022; Released: 2023. Cornell Lab of Ornithology, Ithaca, New York. doi:10.2173/ebirdst.2022
A RasterStack of utilization distributions for a
single Fisher in New York state over the course of nine nights in April 2011.
Cell values represent the probability density that the individual was found
at a given location between sunset and sunrise and the nine layers represent
nine nights of data. Utilization distributions were generated using the
adehabitatHR
package from GPS tracking data.
fisher_ud
fisher_ud
An object of class RasterStack
of dimension 176 x 177 x 9.
https://datarepository.movebank.org/handle/10255/move.330
LaPoint, S., P. Gallery, M. Wikelski, R. Kays. 2013. Animal behavior, cost-based corridor models, and real corridors. Landscape Ecology 28(8): 1615–1630. doi:10.1007/s10980-013-9910-0
LaPoint, S., P. Gallery, M. Wikelski, R. Kays. 2013. Data from: Animal behavior, cost-based corridor models, and real corridors. Movebank Data Repository. doi:10.5441/001/1.2tp2j43g
This function creates a legend to accompany a map describing an unordered set of distributions.
legend_set( palette, specificity = TRUE, group_labels = NULL, label_i = "Maximum\nintensity", label_s = "Specificity", axis_i = c("low", "high"), axis_s = c("low", "high"), return_df = FALSE )
legend_set( palette, specificity = TRUE, group_labels = NULL, label_i = "Maximum\nintensity", label_s = "Specificity", axis_i = c("low", "high"), axis_s = c("low", "high"), return_df = FALSE )
palette |
data frame containing a color palette generated by palette_set. |
specificity |
logical indicating whether to visualize intensity and layer information for the full range of potential specificity values (i.e., 0-100) or for a single specificity value (i.e., 100). Typically, a single specificity value is appropriate for map_multiples visualizations. |
group_labels |
(axis_l) character vector with labels for each distribution. |
label_i |
character vector with a single element describing the meaning of specificity. |
label_s |
character vector with a single element describing the meaning of intensity values. |
axis_i |
character vector with two elements describing the meaning of low and high intensity values. |
axis_s |
character vector with two elements describing the meaning of low and high specificity values. |
return_df |
logical indicating whether to return the legend as a
|
A ggplot2
plot object of the legend. Alternatively,
return_df = TRUE
will return a data frame containing a data frame
containing the data needed to build the legend. The data frame columns are:
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
color
: the hexadecimal color associated with the given layer and
specificity values.
intensity
: maximum cell value across layers divided by the maximum
value across all layers and cells; mapped to alpha level.
legend_timecycle for cyclical sequences of distributions and legend_timeline for linear sequences of distributions.
Other legend:
legend_timecycle()
,
legend_timeline()
# load elephant data data(elephant_ud) # generate hcl palette pal <- palette_set(elephant_ud) # create legend for palettes legend_set(pal)
# load elephant data data(elephant_ud) # generate hcl palette pal <- palette_set(elephant_ud) # create legend for palettes legend_set(pal)
This function creates a legend to accompany a map describing a cyclical sequence of distributions.
legend_timecycle( palette, specificity = TRUE, origin_label = NULL, label_i = "Maximum\nintensity", label_l = "Layer", label_s = c("Low specificity", "Moderate specificity", "High specificity"), return_df = FALSE )
legend_timecycle( palette, specificity = TRUE, origin_label = NULL, label_i = "Maximum\nintensity", label_l = "Layer", label_s = c("Low specificity", "Moderate specificity", "High specificity"), return_df = FALSE )
palette |
data frame containing a color palette generated by palette_timecycle. |
specificity |
logical indicating whether to visualize intensity and layer information for three specificity values (i.e., 0, 50, 100) or for a single specificity value (i.e., 100). Typically, a single specificity value is appropriate for map_multiples visualizations. |
origin_label |
character vector with a single element to be used as the label at the 12 o'clock position of the legend wheel. |
label_i |
character vector with a single element describing the meaning of intensity values. |
label_l |
character vector with a single element describing the meaning of layer values. |
label_s |
character vector with three elements describing differences in the meaning of three specificity values (i.e., 0, 50, 100). |
return_df |
logical indicating whether to return the legend as a
|
A ggplot2
plot object of the legend. Alternatively,
return_df = TRUE
will return a data frame containing the data needed
to build the legend. The data frame columns are:
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
color
: the hexadecimal color associated with the given layer and
specificity values.
intensity
: maximum cell value across layers divided by the maximum
value across all layers and cells; mapped to alpha level.
legend_timeline for linear sequences of distributions and legend_set for distributions of distinct groups.
Other legend:
legend_set()
,
legend_timeline()
# load field sparrow data data(fiespa_occ) # generate hcl palette pal <- palette_timecycle(fiespa_occ) # create legend for palette legend_timecycle(pal)
# load field sparrow data data(fiespa_occ) # generate hcl palette pal <- palette_timecycle(fiespa_occ) # create legend for palette legend_timecycle(pal)
This function creates a legend to accompany a map describing a linear sequence of distributions.
legend_timeline( palette, specificity = TRUE, time_labels = NULL, label_i = "Maximum\nintensity", label_l = "Layer", label_s = c("Low specificity", "Moderate specificity", "High specificity"), axis_i = c("low", "high"), return_df = FALSE )
legend_timeline( palette, specificity = TRUE, time_labels = NULL, label_i = "Maximum\nintensity", label_l = "Layer", label_s = c("Low specificity", "Moderate specificity", "High specificity"), axis_i = c("low", "high"), return_df = FALSE )
palette |
data frame containing a color palette generated by palette_timeline. |
specificity |
logical indicating whether to visualize intensity and layer information for three specificity values (i.e., 0, 50, 100) or for a single specificity value (i.e., 100). Typically, a single specificity value is appropriate for map_multiples visualizations. |
time_labels |
character vector with two elements to be used as labels for the start and end points of the time axis (i.e. x-axis) in the legend. |
label_i |
character vector with a single element describing the meaning of intensity values. |
label_l |
character vector with a single element describing the meaning of layer values. |
label_s |
character vector with three elements describing differences in the meaning of specificity across three legend wheels. |
axis_i |
character vector with two elements describing the meaning of low and high intensity values. |
return_df |
logical indicating whether to return the legend as a
|
A ggplot2
plot object of the legend. Alternatively,
return_df = TRUE
will return a data frame containing a data frame
containing the data needed to build the legend. The data frame columns are:
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
color
: the hexadecimal color associated with the given layer and
specificity values.
intensity
: maximum cell value across layers divided by the maximum
value across all layers and cells; mapped to alpha level.
legend_timecycle for cyclical sequences of distributions and legend_set for distributions of distinct groups.
Other legend:
legend_set()
,
legend_timecycle()
# load fisher data data(fisher_ud) # generate hcl palette pal <- palette_timeline(fisher_ud) # create legend for palette legend_timeline(pal)
# load fisher data data(fisher_ud) # generate hcl palette pal <- palette_timeline(fisher_ud) # create legend for palette legend_timeline(pal)
This function enables visualization of distributional information in a series of small multiples by combining distribution metrics and an HCL color palette.
map_multiples( x, palette, ncol, lambda_i = 0, labels = NULL, return_type = c("plot", "df") )
map_multiples( x, palette, ncol, lambda_i = 0, labels = NULL, return_type = c("plot", "df") )
x |
RasterStack of distributions processed by |
palette |
data frame containing an HCL color palette generated using
|
ncol |
integer specifying the number of columns in the grid of plots. |
lambda_i |
number that allows visual tuning of intensity values via the
|
labels |
character vector of layer labels for each plot. The default is to not show labels. |
return_type |
character specifying whether the function should return a
|
The lambda_i
parameter allows for visual tuning of intensity
values with unusual distributions. For example, distributions often
contain highly skewed intensity values because individuals spend a vast
majority of their time within a relatively small area or because
populations are relatively dense during some seasons and relatively
dispersed during others. This can make visualizing distributions a
challenge. The lambda_i
parameter transforms intensity values via the
scales::modulus_trans()
function, allowing users to adjust the relative
visual weight of high and low intensity values.
By default, or when return_type = "plot"
, the function returns a
map that is a ggplot2
plot object.
When return_type = "df"
, the function returns a data frame containing
eight columns:
x
,y
: coordinates of raster cell centers.
cell_number
: integer indicating the cell number.
layer_cell
: a unique ID for the cell within the layer in the format
"layer-cell_number"
.
intensity
: maximum cell value across layers divided by the maximum
value across all layers and cells; mapped to alpha level.
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
layer_id
: the identity of the raster layer from which an intensity
value was pulled; mapped to hue.
color
: the hexadecimal color associated with the given layer and
specificity values.
Other map:
map_single()
# load fisher data data("fisher_ud") # prepare data r <- metrics_pull(fisher_ud) # generate palette pal <- palette_timeline(fisher_ud) # produce maps, adjusting lambda_i to make areas that were used less # intensively more conspicuous map_multiples(r, pal, lambda_i = -5, labels = paste("night", 1:9))
# load fisher data data("fisher_ud") # prepare data r <- metrics_pull(fisher_ud) # generate palette pal <- palette_timeline(fisher_ud) # produce maps, adjusting lambda_i to make areas that were used less # intensively more conspicuous map_multiples(r, pal, lambda_i = -5, labels = paste("night", 1:9))
This function enables visualization of distributional information in a single map by combining distribution metrics and an HCL color palette.
map_single( x, palette, layer, lambda_i = 0, lambda_s = 0, return_type = c("plot", "stack", "df") )
map_single( x, palette, layer, lambda_i = 0, lambda_s = 0, return_type = c("plot", "stack", "df") )
x |
RasterStack of distributions processed by |
palette |
data frame containing an HCL color palette generated using
|
layer |
integer (or character) corresponding to the layer ID (or name)
of layer. A single distribution from within |
lambda_i |
number that allows visual tuning of intensity values via the
|
lambda_s |
number that allows visual tuning of specificity values via
the |
return_type |
character specifying whether the function should return a
|
The lambda_i
parameter allows for visual tuning of intensity
values with unusual distributions. For example, distributions often
contain highly skewed intensity values because individuals spend a vast
majority of their time within a relatively small area or because
populations are relatively dense during some seasons and relatively
dispersed during others. This can make visualizing distributions a
challenge. The lambda_i
parameter transforms intensity values via the
scales::modulus_trans()
function, allowing users to adjust the relative
visual weight of high and low intensity values.
The lambda_s
parameter allows for visual tuning of specificity
values via the scales::modulus_trans()
function. Adjustment of
lambda_s
affects the distribution of chroma values across areas of
relatively low and high specificity, thus modifying information available
to viewers. USE WITH CAUTION!
By default, or when return_type = "plot"
, the function returns a
map that is a ggplot2
plot object.
When return_type = "stack"
, the function returns a RasterStack
containing five layers that enable RGBa visualization of a map using other
R packages or external GIS software:
R
: red, integer values (0-255).
G
: green, integer values (0-255).
B
: blue, integer values (0-255).
alpha
: opacity, numeric values (0-255).
n_layers
: number of layers in x
with non-NA values.
When return_type = "df"
, the function returns a data frame containing
seven columns:
x
,y
: coordinates of raster cell centers.
cell_number
: integer indicating the cell number within the raster.
intensity
: maximum cell value across layers divided by the maximum
value across all layers and cells; mapped to alpha level.
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
color
: the hexadecimal color associated with the given layer and
specificity values.
Other map:
map_multiples()
# load elephant data data("elephant_ud") # prepare metrics r <- metrics_distill(elephant_ud) # generate palette pal <- palette_set(elephant_ud) # produce map, adjusting lambda_i to make areas that were used less # intensively more conspicuous map_single(r, pal, lambda_i = -5) # return RasterStack containing RGBa values m <- map_single(r, pal, lambda_i = -5, return_type = "stack") # visualize RGBa values library(raster) plotRGB(m, 1, 2, 3, alpha = as.vector(m[[4]]))
# load elephant data data("elephant_ud") # prepare metrics r <- metrics_distill(elephant_ud) # generate palette pal <- palette_set(elephant_ud) # produce map, adjusting lambda_i to make areas that were used less # intensively more conspicuous map_single(r, pal, lambda_i = -5) # return RasterStack containing RGBa values m <- map_single(r, pal, lambda_i = -5, return_type = "stack") # visualize RGBa values library(raster) plotRGB(m, 1, 2, 3, alpha = as.vector(m[[4]]))
This function is used to summarize several distributional features of interest across a series of distributions. Distributional information in the original raster stack is "distilled" for subsequent visualization.
metrics_distill(x)
metrics_distill(x)
x |
RasterStack of distributions. Layers typically contain information about the distribution of a single individual or species at multiple points in time. Alternatively, layers may contain information about the distributions of multiple individuals or species within a single time period. Other conceptualizations are possible. |
Specificity values range from 0 to 100. Values of 0 indicate intensity values are identical in all layers. Values of 100 indicate intensity values are restricted to a single layer. Interpretation of specificity values depends on the layers provided. If layers describe the distribution of a species at different times of the year, specificity can be interpreted as a measure of seasonality (i.e., 0 = stable year-round occurrence in a cell, 100 = highly seasonal occurrence). If layers describe space use by multiple individuals, specificity can be interpreted as a measure of exclusivity (i.e., 0 = equal use of a cell by all individuals, 100 = exclusive use by one individual).
The number of layers with non-NA values is recorded to aid interpretation of distributions. Ideally, n_layers values are identical in every cell, indicating that users have knowledge of distributions over the same area in every layer of their raster stack. When n_layers values are unequal, it indicates that users have unequal knowledge of distributions in their raster stack. Distributions are more likely to be misrepresented and misinterpreted if cells do not contain intensity values in every layer.
A RasterStack with four layers:
intensity
: the maximum intensity value across all layers.
layer_id
: an integer identifying layer containing the maximum intensity
value.
specificity
: the degree to which intensity values are unevenly
distributed across layers (see Details).
n_layers
: the number of layers with non-NA values (see Details).
The maximum cell value in the stack is stored as the "maximum"
attribute.
The link between the layer_id
and the layer names from the underlying
raster is stored as a data frame in the layer_names
attribute.
Other metrics:
metrics_pull()
# load elephant data data("elephant_ud") # distill r <- metrics_distill(elephant_ud) print(r) # maximum value across all layers stored as an attribute attr(r, "maximum") # link between layer id and name stored as an attribute attr(r, "layer_names")
# load elephant data data("elephant_ud") # distill r <- metrics_distill(elephant_ud) print(r) # maximum value across all layers stored as an attribute attr(r, "maximum") # link between layer id and name stored as an attribute attr(r, "layer_names")
This function transforms raster stack values that describe individual distributions or species distributions into standardized intensity values. All the distributional information in the original raster stack is preserved for visualization.
metrics_pull(x)
metrics_pull(x)
x |
RasterStack of distributions. Layers typically contain information about the distribution of a single individual or species at multiple points in time. Alternatively, layers may contain information about the distributions of multiple individuals or species within a single time period. Other conceptualizations are possible. |
A RasterStack containing intensity values. Intensity values are calculated by dividing cell values in every layer by the maximum cell value in the entire stack, thus ensuring intensities are comparable across layers.
The maximum cell value in the stack is stored as the "maximum"
attribute.
Other metrics:
metrics_distill()
# load elephant data data("elephant_ud") r <- metrics_pull(elephant_ud) print(r) # maximum value for the stack stored as an attribute attr(r, "maximum")
# load elephant data data("elephant_ud") r <- metrics_pull(elephant_ud) print(r) # maximum value for the stack stored as an attribute attr(r, "maximum")
This function generates an HCL palette for visualizing a small set of distributions (i.e., eight or fewer) that are not ordered in a linear or cyclical sequence (e.g., a set of utilization distributions describing space use by five separate individuals in the same population or a set of four species distributions that depend on similar food resources).
palette_set(x, custom_hues)
palette_set(x, custom_hues)
x |
RasterStack or integer describing the number of layers for which colors need to be generated. |
custom_hues |
vector of integers between -360 and 360 representing
hues in the color wheel. For further details, consult the documentation
for colorspace::rainbow_hcl. The length of the vector must equal the
number of layers described by |
A data frame with three columns:
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
color
: the hexadecimal color associated with the given layer and
specificity values.
palette_timecycle for cyclical sequences of distributions and palette_timeline for linear sequences of distributions.
Other palette:
palette_timecycle()
,
palette_timeline()
# load elephant data data(elephant_ud) # generate hcl color palette pal <- palette_set(elephant_ud) head(pal) # visualize the palette in HCL space with colorspace::hclplot library(colorspace) hclplot(pal[pal$specificity == 100, ]$color)
# load elephant data data(elephant_ud) # generate hcl color palette pal <- palette_set(elephant_ud) head(pal) # visualize the palette in HCL space with colorspace::hclplot library(colorspace) hclplot(pal[pal$specificity == 100, ]$color)
This function generates an HCL palette for visualizing a cyclical sequence of distributions (e.g., a series of distributions describing species occurrence in each of 52 weeks of the annual cycle or a series of utilization distributions describing typical space use by an individual animal in each hour of a 24-hour daily cycle).
palette_timecycle(x, start_hue = 240, clockwise = TRUE)
palette_timecycle(x, start_hue = 240, clockwise = TRUE)
x |
RasterStack or integer describing the number of layers for which colors need to be generated. |
start_hue |
integer between -360 and 360 representing the starting hue in an HCL color wheel. For further details, consult the documentation for colorspace::rainbow_hcl. The default value of 240 will start the palette at "blue". |
clockwise |
logical indicating which direction to move around color
wheel. The default |
A data frame with three columns:
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
color
: the hexadecimal color associated with the given layer and
specificity values.
palette_timeline for linear sequences of distributions and palette_set for unordered sets of distributions.
Other palette:
palette_set()
,
palette_timeline()
# load field sparrow data data(fiespa_occ) # generate hcl color palette pal <- palette_timecycle(fiespa_occ) head(pal) # visualize the palette in HCL space with colorspace::hclplot library(colorspace) hclplot(pal[pal$specificity == 100, ]$color)
# load field sparrow data data(fiespa_occ) # generate hcl color palette pal <- palette_timecycle(fiespa_occ) head(pal) # visualize the palette in HCL space with colorspace::hclplot library(colorspace) hclplot(pal[pal$specificity == 100, ]$color)
This function generates an HCL palette for visualizing a linear sequence of distributions (e.g., a series of utilization distributions describing space use by an individual animal across each of 20 consecutive days or a series of species distributions describing projected responses to global warming in 0.5 C increments).
palette_timeline(x, start_hue = -130, clockwise = FALSE)
palette_timeline(x, start_hue = -130, clockwise = FALSE)
x |
RasterStack or integer describing the number of layers for which colors need to be generated. |
start_hue |
integer between -360 and 360 representing the starting hue in the color wheel. For further details, consult the documentation for colorspace::rainbow_hcl. Recommended values are -130 ("blue-pink-yellow" palette) and 50 ("yellow-green-blue" palette). |
clockwise |
logical indicating which direction to move around an HCL
color wheel. When |
A data frame with three columns:
layer_id
: integer identifying the layer containing the maximum
intensity value; mapped to hue.
specificity
: the degree to which intensity values are unevenly
distributed across layers; mapped to chroma.
color
: the hexadecimal color associated with the given layer and
specificity values.
palette_timecycle for cyclical sequences of distributions and palette_set for unordered sets of distributions.
Other palette:
palette_set()
,
palette_timecycle()
# load fisher data data(fisher_ud) # generate hcl color palette pal_a <- palette_timeline(fisher_ud) head(pal_a) # use a clockwise palette pal_b <- palette_timeline(fisher_ud, clockwise = TRUE) # try a different starting hue pal_c <- palette_timeline(fisher_ud, start = 50) # visualize the palette in HCL space with colorspace::hclplot library(colorspace) hclplot(pal_a[pal_a$specificity == 100, ]$color) hclplot(pal_b[pal_b$specificity == 100, ]$color) hclplot(pal_c[pal_c$specificity == 100, ]$color)
# load fisher data data(fisher_ud) # generate hcl color palette pal_a <- palette_timeline(fisher_ud) head(pal_a) # use a clockwise palette pal_b <- palette_timeline(fisher_ud, clockwise = TRUE) # try a different starting hue pal_c <- palette_timeline(fisher_ud, start = 50) # visualize the palette in HCL space with colorspace::hclplot library(colorspace) hclplot(pal_a[pal_a$specificity == 100, ]$color) hclplot(pal_b[pal_b$specificity == 100, ]$color) hclplot(pal_c[pal_c$specificity == 100, ]$color)