Nothing
#' Add title, subtitle and caption to a spectral plot
#'
#' Add a title, subtitle and caption to a spectral plot based on automatically
#' extracted metadata from an spectral object.
#'
#' @param object generic_spct or generic_mspct The spectral object plotted.
#' @param object.label character The name of the object being plotted.
#' @param annotations character vector Annotations as described for
#' \code{plot()} methods, values unrelated to title are ignored.
#' @param time.format character Format as accepted by
#' \code{\link[base]{strptime}}.
#' @param tz character time zone used in labels.
#' @param default.title character vector The default used for \code{annotations
#' = "title"}.
#'
#' @section Title Annotations: metadata retrieved from object \code{object} is
#' paased to \code{ggplot2::ggtitle()} as arguments for \code{title},
#' \code{subtitle} and \code{caption}. The specification for the title is
#' passed as argument to \code{annotations}, and consists in the keyword
#' \code{title} with optional modifiers selecting the kind of metatdata to
#' use, separated by colons. Up to three keywords separated by colons are
#' accepted, and correspond to title, subtitle and caption. The recognized
#' keywords are: \code{"objt"}, \code{"class"}, \code{"what"}, \code{"when"},
#' \code{"where"}, \code{"how"}, \code{"inst.name"}, \code{"inst.sn"},
#' \code{"comment"} and \code{"none"} are recognized as modifiers to
#' \code{"title"}; \code{"none"} is a placeholder. Default is
#' \code{"title:objt"} or no title depending on the context.
#'
#' @return The return value of \code{ggplot2::labs()}.
#'
#' @examples
#'
#' p <- ggplot(sun.spct) +
#' geom_line()
#'
#' p + autotitle(sun.spct)
#' p + autotitle(sun.spct, object.label = "The terrestrial solar spectrum")
#' p + autotitle(sun.spct, annotations = "title:objt:class")
#' p + autotitle(sun.spct, annotations = "title:where:when:how")
#'
#' p <- ggplot(sun_evening.spct) +
#' aes(linetype = spct.idx) +
#' geom_line()
#'
#' p + autotitle(sun_evening.spct, annotations = "title:objt:class")
#' p + autotitle(sun_evening.spct, annotations = "title:where:when:how")
#' p + autotitle(sun_evening.spct, annotations = "title:none:none:how")
#'
#' p <- ggplot(sun_evening.mspct) +
#' aes(linetype = spct.idx) +
#' geom_line()
#'
#' p + autotitle(sun_evening.mspct, annotations = "title:objt:class")
#'
#' @export
#'
autotitle <- function(object,
object.label = deparse(substitute(object)),
annotations = "title",
time.format = NULL,
tz = "",
default.title = "title:objt") {
force(object.label)
if (!is.character(object.label)) {
if (is.name(object.label)) {
object.label <- as.character(object.label)
} else {
object.label <- paste("anonymous '", class(object)[1], "'", sep = "")
}
}
if (is.null(time.format) || all(time.format == "")) {
time.format <- c("%Y-%m-%d %H:%M", "%H:%M")
} else if (length(time.format) == 1) {
time.format <- rep(time.format, 2)
}
class.object <- class(object)[1]
# this makes it possible to support collections
# maybe not needed with current versions 'photobiology' >= 0.11.1
if (is.generic_mspct(object)) {
object <- rbindspct(object)
}
get_title_text <- function(key) {
switch(key,
objt = object.label,
class = class.object,
what =
{
what <- getWhatMeasured(object)
if (all(is.na(what))) {
what <- "what measured not known"
}
if (is.list(what)) {
what <- unique(what)
if (length(what) == 1) {
what
} else {
""
}
} else {
what
}
},
how =
{
how <- getHowMeasured(object)
if (all(is.na(how))) {
how <- "how measured not known"
} else {
if (is.list(how)) {
how <- unique(how)
if (length(how) == 1) {
how
} else {
"how measured varies"
}
} else {
how
}
}
},
when =
{
when <- getWhenMeasured(object)
if (all(is.na(when))) {
when <- "when measured not known"
} else {
if (is.list(when)) {
when <- as.POSIXct(unique(range(when, na.rm = TRUE)), tz = tz)
if (length(when) > 1L &&
(when[2] - when[1]) >= lubridate::ddays(1)) {
time.format[2] <- time.format[1]
}
}
if(length(when) == 1) {
strftime(x = when[1],
format = time.format[1],
tz = tz,
usetz = TRUE)
} else if(length(when) == 2) {
paste(
strftime(x = when[1],
format = time.format[1],
tz = tz,
usetz = FALSE),
strftime(x = when[2],
format = time.format[2],
tz = tz,
usetz = TRUE),
sep = " to ")
}
}
},
where =
{
where <- getWhereMeasured(object)
if (all(is.na(where$lon)) && all(is.na(where$lat))) {
"where measured not know"
} else {
if (!is.data.frame(where) && is.list(where)) {
where <- unique(where)
if (length(where) == 1) {
where <- where[[1]] # extract list member
} else {
where <- "where measured varies"
}
}
if (is.data.frame(where) &&
(!(anyNA(where[["lon"]]) | anyNA(where[["lat"]])))) {
where[["lon"]] <- ifelse(where[["lon"]] < 0,
paste(abs(where[["lon"]]), " W"),
paste(where[["lon"]], " E"))
where[["lat"]] <- ifelse(where[["lat"]] < 0,
paste(abs(where[["lat"]]), " S"),
paste(where[["lat"]], " N"))
where[["address"]] <- ifelse(is.na(where[["address"]]),
character(),
as.character(where[["address"]]))
# the order of columns in the data frame can vary
paste(where[["lat"]], where[["lon"]], where[["address"]], sep = ", ")
} else {
where
}
}
},
inst.name =
{
descriptor <- getInstrDesc(object)
if (all(is.na(descriptor))) {
descriptor <- "instrument name not known"
} else {
if (inherits(descriptor, "instr_desc")) {
inst.names <- descriptor[["spectrometer.name"]]
} else {
inst.names <- sapply(descriptor, `[[`, i = "spectrometer.name")
inst.names <- unique(inst.names)
}
if (length(inst.names) == 1) {
inst.names
} else {
"multiple instrument names"
}
}
},
inst.sn =
{
descriptor <- getInstrDesc(object)
if (all(is.na(descriptor))) {
descriptor <- "instrument serial number not known"
} else {
if (inherits(descriptor, "instr_desc")) {
inst.sns <- descriptor[["spectrometer.sn"]]
} else {
inst.sns <- sapply(descriptor, `[[`, i = "spectrometer.sn")
inst.sns <- unique(inst.sns)
}
if (length(inst.sns) == 1) {
inst.sns
} else {
"multiple instrument units"
}
}
},
comment = comment(object),
num.spct = paste("n =", getMultipleWl(object)),
none = NULL,
{
warning("Title key '", key, "' not recognized"); NULL
}
)
}
title.ann <- grep("^title", annotations, value = TRUE)
if (length(title.ann) == 0) {
return(NULL)
} else if (title.ann[1] == "title") {
# default title
title.ann <- default.title
}
# we avoid calling tz() on lists as returned for multiple spectra
when.measured <- getWhenMeasured(object)
if (is.data.frame(when.measured)) {
when.measured <- unique(range(when.measured[["when.measured"]]))
}
if (is.null(tz)) {
if (lubridate::is.instant(when.measured[1])) {
tz <- lubridate::tz(when.measured[1])
if (tz == "") {
# [2021-09-30] this may happen if the user uses lubridate::now()
tz <- Sys.timezone()
}
} else {
tz <- NA_character_
}
}
title.ann <- c(strsplit(title.ann[1], ":")[[1]][-1], "none", "none", "none")
title <- get_title_text(title.ann[1])
subtitle <- get_title_text(title.ann[2])
caption <- get_title_text(title.ann[3])
# this is equivalent to ggtitle(tittle, subtitle)
ggplot2::labs(title = title, subtitle = subtitle, caption = caption)
}
#' @rdname autotitle
#'
#' @note Method renamed as \code{autotitle()} to better reflect its function;
#' \code{ggtitle_spct()} is deprecated but will remain available for backwards
#' compatibility.
#'
#' @export
#'
ggtitle_spct <- autotitle
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.