diff --git a/R/geom-.R b/R/geom-.R index 50bdeb66a6..74efe6cec6 100644 --- a/R/geom-.R +++ b/R/geom-.R @@ -133,7 +133,7 @@ Geom <- ggproto("Geom", # Fill in missing aesthetics with their defaults missing_aes <- setdiff(names(default_aes), names(data)) default_aes <- default_aes[missing_aes] - themed_defaults <- eval_from_theme(default_aes, theme) + themed_defaults <- eval_from_theme(default_aes, theme, class(self)) default_aes[names(themed_defaults)] <- themed_defaults # Mark staged/scaled defaults as modifier (#6135) @@ -243,13 +243,33 @@ Geom <- ggproto("Geom", #' @rdname is_tests is.geom <- function(x) inherits(x, "Geom") -eval_from_theme <- function(aesthetics, theme) { +eval_from_theme <- function(aesthetics, theme, class = NULL) { themed <- is_themed_aes(aesthetics) if (!any(themed)) { return(aesthetics) } - settings <- calc_element("geom", theme) %||% .default_geom_element - lapply(aesthetics[themed], eval_tidy, data = settings) + + element <- calc_element("geom", theme) %||% .default_geom_element + class <- setdiff(class, c("Geom", "ggproto", "gg")) + + if (length(class) > 0) { + + # CamelCase to dot.case + class <- gsub("([A-Za-z])([A-Z])([a-z])", "\\1.\\2\\3", class) + class <- gsub("([a-z])([A-Z])", "\\1.\\2", class) + class <- to_lower_ascii(class) + + class <- class[class %in% names(theme)] + + # Inherit up to parent geom class + if (length(class) > 0) { + for (cls in rev(class)) { + element <- combine_elements(theme[[cls]], element) + } + } + } + + lapply(aesthetics[themed], eval_tidy, data = element) } #' Graphical units