#' Create a ggplot2 annotation given some aesthetics, parameters, and
#' facet variables + values.
#'
#' This function is based on ggplot2::annotate(). The two main differences are:
#' it returns an unevaluated function call rather than a ggproto object; and
#' it can handle limiting annotations to (specified) facet level(s).
#'
#' @param geom Geom to annotate, such as "text".
#' @param aes Named list of aesthetics with corresponding data values, as in
#' `list(x = 3, y = 30, label = "A label")`.
#' @param params Optional. Named list of parameters for geom,
#' such as `list(colour = "black")`
#' @param facets Optional. Named list of facets; the name is the variable and
#' the value if the level, such as `list(cyl = 4)`.
#' @return A call
#'
#' @examples
#' library(ggplot2)
#'
#' base_plot <- ggplot(mtcars, aes(x = wt, y = mpg)) +
#' geom_point() +
#' facet_wrap(~cyl)
#'
#' my_annot_call <- make_layer("text",
#' aes = list(x = 3, y = 30, label = "A label"),
#' facets = list(cyl = 6),
#' params = list(col = "red")
#' )
#'
#' my_annotation <- eval(my_annot_call)
#'
#' base_plot + my_annotation
#' @export
#'
#' @importFrom purrr compact
#' @importFrom rlang call2 syms `!!!`
#' @importFrom stats setNames
make_layer <- function(geom,
aes = NULL,
params = NULL,
facets = NULL) {
compact_aes <- purrr::compact(aes)
aesthetics <- rlang::syms(names(compact_aes))
names(aesthetics) <- aesthetics
aes_call <- rlang::call2("aes", !!!aesthetics)
# Dates
date_call <- function(arg) {
if (inherits(arg, "Date")) {
arg <- as.character(arg)
arg <- call("as.Date", arg)
}
arg
}
data_cols <- lapply(compact_aes, date_call)
# Facets
if (isFALSE(missing(facets)) && length(facets) > 0) {
if (is.null(names(facets))) {
stop("facets must be a named list")
}
data_cols <- c(data_cols, facets)
}
data_call <- rlang::call2("data.frame", !!!data_cols)
params_list <- purrr::compact(params)
geom_to_call <- paste0("geom_", geom)
params_list <- remove_default_params(geom_to_call, params_list)
rlang::call2(geom_to_call,
data = data_call,
mapping = aes_call,
!!!params_list,
inherit.aes = FALSE
)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.