From 3ce823d8098e937bdd63f87067ac540ff582fae8 Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Fri, 4 May 2018 00:16:56 -0500 Subject: [PATCH 01/10] enable guide_colorbar to work with nonstandard aesthetics --- R/guide-colorbar.r | 12 +++++++++--- man/guide_colourbar.Rd | 9 +++++++-- 2 files changed, 16 insertions(+), 5 deletions(-) diff --git a/R/guide-colorbar.r b/R/guide-colorbar.r index ba36da68d2..ea6d4f505c 100644 --- a/R/guide-colorbar.r +++ b/R/guide-colorbar.r @@ -44,6 +44,8 @@ #' for `barwidth` and `barheight`. #' @param reverse logical. If `TRUE` the colorbar is reversed. By default, #' the highest value is on the top and the lowest value is on the bottom +#' @param available_aes A vector of charater strings listing the aesthetics +#' for which a colorbar can be drawn. #' @param ... ignored. #' @return A guide object #' @export @@ -134,6 +136,7 @@ guide_colourbar <- function( default.unit = "line", reverse = FALSE, order = 0, + available_aes = c("colour", "color", "fill"), ...) { @@ -180,7 +183,9 @@ guide_colourbar <- function( order = order, # parameter - available_aes = c("colour", "color", "fill"), ..., name = "colorbar"), + available_aes = available_aes, + ..., + name = "colorbar"), class = c("guide", "colorbar") ) } @@ -189,8 +194,9 @@ guide_colourbar <- function( guide_train.colorbar <- function(guide, scale) { # do nothing if scale are inappropriate - if (length(intersect(scale$aesthetics, c("color", "colour", "fill"))) == 0) { - warning("colorbar guide needs colour or fill scales.") + if (length(intersect(scale$aesthetics, guide$available_aes)) == 0) { + warning("colorbar guide needs appropriate scales: ", + paste(guide$available_aes, collapse = ", ")) return(NULL) } if (scale$is_discrete()) { diff --git a/man/guide_colourbar.Rd b/man/guide_colourbar.Rd index c4be437441..3d48aeeef8 100644 --- a/man/guide_colourbar.Rd +++ b/man/guide_colourbar.Rd @@ -13,7 +13,8 @@ guide_colourbar(title = waiver(), title.position = NULL, frame.linewidth = 0.5, frame.linetype = 1, ticks = TRUE, ticks.colour = "white", ticks.linewidth = 0.5, draw.ulim = TRUE, draw.llim = TRUE, direction = NULL, default.unit = "line", - reverse = FALSE, order = 0, ...) + reverse = FALSE, order = 0, available_aes = c("colour", "color", + "fill"), ...) guide_colorbar(title = waiver(), title.position = NULL, title.theme = NULL, title.hjust = NULL, title.vjust = NULL, @@ -23,7 +24,8 @@ guide_colorbar(title = waiver(), title.position = NULL, frame.linewidth = 0.5, frame.linetype = 1, ticks = TRUE, ticks.colour = "white", ticks.linewidth = 0.5, draw.ulim = TRUE, draw.llim = TRUE, direction = NULL, default.unit = "line", - reverse = FALSE, order = 0, ...) + reverse = FALSE, order = 0, available_aes = c("colour", "color", + "fill"), ...) } \arguments{ \item{title}{A character string or expression indicating a title of guide. @@ -114,6 +116,9 @@ this guide among multiple guides. This controls the order in which multiple guides are displayed, not the contents of the guide itself. If 0 (default), the order is determined by a secret algorithm.} +\item{available_aes}{A vector of charater strings listing the aesthetics +for which a colorbar can be drawn.} + \item{...}{ignored.} } \value{ From 3794036f8ea4396c301818f567dff59198bbb84f Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Fri, 4 May 2018 15:50:48 -0500 Subject: [PATCH 02/10] remove hardcoded aesthetics setting for scales; adjust guides so they can make full use of multiple aesthetics for one scale. --- R/guide-colorbar.r | 4 ++-- R/guide-legend.r | 4 ++-- R/guides-.r | 49 ++++++++++++++++++++++--------------------- R/scale-alpha.r | 18 +++++++++------- R/scale-brewer.r | 16 +++++++------- R/scale-gradient.r | 32 +++++++++++++++++----------- R/scale-grey.r | 8 +++---- R/scale-hue.r | 14 ++++++++----- R/scale-identity.r | 25 +++++++++++----------- R/scale-linetype.r | 8 ++++--- R/scale-manual.r | 28 +++++++++++++------------ R/scale-shape.r | 8 ++++--- R/scale-size.r | 26 ++++++++++++----------- R/scale-viridis.r | 20 ++++++++++-------- man/guide-exts.Rd | 2 +- man/scale_alpha.Rd | 9 +++++--- man/scale_brewer.Rd | 13 ++++++++---- man/scale_gradient.Rd | 16 ++++++++------ man/scale_grey.Rd | 9 ++++++-- man/scale_hue.Rd | 8 ++++--- man/scale_identity.Rd | 14 +++++++------ man/scale_linetype.Rd | 8 ++++--- man/scale_manual.Rd | 16 +++++++------- man/scale_shape.Rd | 6 ++++-- man/scale_size.Rd | 11 +++++++--- man/scale_viridis.Rd | 11 ++++++---- 26 files changed, 222 insertions(+), 161 deletions(-) diff --git a/R/guide-colorbar.r b/R/guide-colorbar.r index ea6d4f505c..b1a89f391e 100644 --- a/R/guide-colorbar.r +++ b/R/guide-colorbar.r @@ -191,7 +191,7 @@ guide_colourbar <- function( } #' @export -guide_train.colorbar <- function(guide, scale) { +guide_train.colorbar <- function(guide, scale, aesthetic = NULL) { # do nothing if scale are inappropriate if (length(intersect(scale$aesthetics, guide$available_aes)) == 0) { @@ -210,7 +210,7 @@ guide_train.colorbar <- function(guide, scale) { if (length(breaks) == 0 || all(is.na(breaks))) return() - ticks <- as.data.frame(setNames(list(scale$map(breaks)), scale$aesthetics[1])) + ticks <- as.data.frame(setNames(list(scale$map(breaks)), aesthetic %||% scale$aesthetics[1])) ticks$.value <- breaks ticks$.label <- scale$get_labels(breaks) diff --git a/R/guide-legend.r b/R/guide-legend.r index 383e2ffa17..d53894cd88 100644 --- a/R/guide-legend.r +++ b/R/guide-legend.r @@ -215,14 +215,14 @@ guide_legend <- function(# title } #' @export -guide_train.legend <- function(guide, scale) { +guide_train.legend <- function(guide, scale, aesthetic = NULL) { breaks <- scale$get_breaks() if (length(breaks) == 0 || all(is.na(breaks))) { return() } key <- as.data.frame( - setNames(list(scale$map(breaks)), scale$aesthetics[1]), + setNames(list(scale$map(breaks)), aesthetic %||% scale$aesthetics[1]), stringsAsFactors = FALSE ) key$.label <- scale$get_labels(breaks) diff --git a/R/guides-.r b/R/guides-.r index 904cb32339..8a05ea8f8a 100644 --- a/R/guides-.r +++ b/R/guides-.r @@ -162,37 +162,38 @@ guides_train <- function(scales, theme, guides, labels) { gdefs <- list() for (scale in scales$scales) { + for (output in scale$aesthetics) { - # guides(XXX) is stored in guides[[XXX]], - # which is prior to scale_ZZZ(guide=XXX) - # guide is determined in order of: - # + guides(XXX) > + scale_ZZZ(guide=XXX) > default(i.e., legend) - output <- scale$aesthetics[1] - guide <- guides[[output]] %||% scale$guide + # guides(XXX) is stored in guides[[XXX]], + # which is prior to scale_ZZZ(guide=XXX) + # guide is determined in order of: + # + guides(XXX) > + scale_ZZZ(guide=XXX) > default(i.e., legend) + guide <- guides[[output]] %||% scale$guide - # this should be changed to testing guide == "none" - # scale$legend is backward compatibility - # if guides(XXX=FALSE), then scale_ZZZ(guides=XXX) is discarded. - if (guide == "none" || (is.logical(guide) && !guide)) next + # this should be changed to testing guide == "none" + # scale$legend is backward compatibility + # if guides(XXX=FALSE), then scale_ZZZ(guides=XXX) is discarded. + if (guide == "none" || (is.logical(guide) && !guide)) next - # check the validity of guide. - # if guide is character, then find the guide object - guide <- validate_guide(guide) + # check the validity of guide. + # if guide is character, then find the guide object + guide <- validate_guide(guide) - # check the consistency of the guide and scale. - if (guide$available_aes != "any" && !scale$aesthetics %in% guide$available_aes) - stop("Guide '", guide$name, "' cannot be used for '", scale$aesthetics, "'.") + # check the consistency of the guide and scale. + if (guide$available_aes != "any" && !scale$aesthetics %in% guide$available_aes) + stop("Guide '", guide$name, "' cannot be used for '", scale$aesthetics, "'.") - guide$title <- scale$make_title(guide$title %|W|% scale$name %|W|% labels[[output]]) + guide$title <- scale$make_title(guide$title %|W|% scale$name %|W|% labels[[output]]) - # direction of this grob - guide$direction <- guide$direction %||% theme$legend.direction + # direction of this grob + guide$direction <- guide$direction %||% theme$legend.direction - # each guide object trains scale within the object, - # so Guides (i.e., the container of guides) need not to know about them - guide <- guide_train(guide, scale) + # each guide object trains scale within the object, + # so Guides (i.e., the container of guides) need not to know about them + guide <- guide_train(guide, scale, output) - if (!is.null(guide)) gdefs[[length(gdefs) + 1]] <- guide + if (!is.null(guide)) gdefs[[length(gdefs) + 1]] <- guide + } } gdefs } @@ -309,7 +310,7 @@ NULL #' @export #' @rdname guide-exts -guide_train <- function(guide, scale) UseMethod("guide_train") +guide_train <- function(guide, scale, aesthetic = NULL) UseMethod("guide_train") #' @export #' @rdname guide-exts diff --git a/R/scale-alpha.r b/R/scale-alpha.r index 967ae92d9a..c9d2d0d33c 100644 --- a/R/scale-alpha.r +++ b/R/scale-alpha.r @@ -8,6 +8,8 @@ #' @param ... Other arguments passed on to [continuous_scale()] #' or [discrete_scale()] as appropriate, to control name, limits, #' breaks, labels and so forth. +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @param range Output range of alpha values. Must lie between 0 and 1. #' @family colour scales #' @export @@ -18,8 +20,8 @@ #' p #' p + scale_alpha("cylinders") #' p + scale_alpha(range = c(0.4, 0.8)) -scale_alpha <- function(..., range = c(0.1, 1)) { - continuous_scale("alpha", "alpha_c", rescale_pal(range), ...) +scale_alpha <- function(..., range = c(0.1, 1), aesthetics = "alpha") { + continuous_scale(aesthetics, "alpha_c", rescale_pal(range), ...) } #' @rdname scale_alpha @@ -35,9 +37,9 @@ scale_alpha_discrete <- function(...) { #' @rdname scale_alpha #' @export -scale_alpha_ordinal <- function(..., range = c(0.1, 1)) { +scale_alpha_ordinal <- function(..., range = c(0.1, 1), aesthetics = "alpha") { discrete_scale( - "alpha", + aesthetics, "alpha_d", function(n) seq(range[1], range[2], length.out = n), ... @@ -47,13 +49,13 @@ scale_alpha_ordinal <- function(..., range = c(0.1, 1)) { #' @rdname scale_alpha #' @export #' @usage NULL -scale_alpha_datetime <- function(..., range = c(0.1, 1)) { - datetime_scale("alpha", "time", palette = rescale_pal(range), ...) +scale_alpha_datetime <- function(..., range = c(0.1, 1), aesthetics = "alpha") { + datetime_scale(aesthetics, "time", palette = rescale_pal(range), ...) } #' @rdname scale_alpha #' @export #' @usage NULL -scale_alpha_date <- function(..., range = c(0.1, 1)){ - datetime_scale("alpha", "date", palette = rescale_pal(range), ...) +scale_alpha_date <- function(..., range = c(0.1, 1), aesthetics = "alpha"){ + datetime_scale(aesthetics, "date", palette = rescale_pal(range), ...) } diff --git a/R/scale-brewer.r b/R/scale-brewer.r index b0c99dbb7a..0b16528a9f 100644 --- a/R/scale-brewer.r +++ b/R/scale-brewer.r @@ -65,37 +65,37 @@ #' v #' v + scale_fill_distiller() #' v + scale_fill_distiller(palette = "Spectral") -scale_colour_brewer <- function(..., type = "seq", palette = 1, direction = 1) { - discrete_scale("colour", "brewer", brewer_pal(type, palette, direction), ...) +scale_colour_brewer <- function(..., type = "seq", palette = 1, direction = 1, aesthetics = "colour") { + discrete_scale(aesthetics, "brewer", brewer_pal(type, palette, direction), ...) } #' @export #' @rdname scale_brewer -scale_fill_brewer <- function(..., type = "seq", palette = 1, direction = 1) { - discrete_scale("fill", "brewer", brewer_pal(type, palette, direction), ...) +scale_fill_brewer <- function(..., type = "seq", palette = 1, direction = 1, aesthetics = "fill") { + discrete_scale(aesthetics, "brewer", brewer_pal(type, palette, direction), ...) } #' @export #' @rdname scale_brewer -scale_colour_distiller <- function(..., type = "seq", palette = 1, direction = -1, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar") { +scale_colour_distiller <- function(..., type = "seq", palette = 1, direction = -1, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar", aesthetics = "colour") { # warn about using a qualitative brewer palette to generate the gradient type <- match.arg(type, c("seq", "div", "qual")) if (type == "qual") { warning("Using a discrete colour palette in a continuous scale.\n Consider using type = \"seq\" or type = \"div\" instead", call. = FALSE) } - continuous_scale("colour", "distiller", + continuous_scale(aesthetics, "distiller", gradient_n_pal(brewer_pal(type, palette, direction)(6), values, space), na.value = na.value, guide = guide, ...) # NB: 6 colours per palette gives nice gradients; more results in more saturated colours which do not look as good } #' @export #' @rdname scale_brewer -scale_fill_distiller <- function(..., type = "seq", palette = 1, direction = -1, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar") { +scale_fill_distiller <- function(..., type = "seq", palette = 1, direction = -1, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar", aesthetics = "fill") { type <- match.arg(type, c("seq", "div", "qual")) if (type == "qual") { warning("Using a discrete colour palette in a continuous scale.\n Consider using type = \"seq\" or type = \"div\" instead", call. = FALSE) } - continuous_scale("fill", "distiller", + continuous_scale(aesthetics, "distiller", gradient_n_pal(brewer_pal(type, palette, direction)(6), values, space), na.value = na.value, guide = guide, ...) } diff --git a/R/scale-gradient.r b/R/scale-gradient.r index cf0c440a5c..7923d3217d 100644 --- a/R/scale-gradient.r +++ b/R/scale-gradient.r @@ -54,15 +54,17 @@ #' scale_colour_gradient(low = "white", high = "black") #' # Avoid red-green colour contrasts because ~10% of men have difficulty #' # seeing them -scale_colour_gradient <- function(..., low = "#132B43", high = "#56B1F7", space = "Lab", na.value = "grey50", guide = "colourbar") { - continuous_scale("colour", "gradient", seq_gradient_pal(low, high, space), +scale_colour_gradient <- function(..., low = "#132B43", high = "#56B1F7", space = "Lab", + na.value = "grey50", guide = "colourbar", aesthetics = "colour") { + continuous_scale(aesthetics, "gradient", seq_gradient_pal(low, high, space), na.value = na.value, guide = guide, ...) } #' @rdname scale_gradient #' @export -scale_fill_gradient <- function(..., low = "#132B43", high = "#56B1F7", space = "Lab", na.value = "grey50", guide = "colourbar") { - continuous_scale("fill", "gradient", seq_gradient_pal(low, high, space), +scale_fill_gradient <- function(..., low = "#132B43", high = "#56B1F7", space = "Lab", + na.value = "grey50", guide = "colourbar", aesthetics = "fill") { + continuous_scale(aesthetics, "gradient", seq_gradient_pal(low, high, space), na.value = na.value, guide = guide, ...) } @@ -71,16 +73,20 @@ scale_fill_gradient <- function(..., low = "#132B43", high = "#56B1F7", space = #' Defaults to 0. #' @rdname scale_gradient #' @export -scale_colour_gradient2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"), midpoint = 0, space = "Lab", na.value = "grey50", guide = "colourbar") { - continuous_scale("colour", "gradient2", +scale_colour_gradient2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"), + midpoint = 0, space = "Lab", na.value = "grey50", guide = "colourbar", + aesthetics = "colour") { + continuous_scale(aesthetics, "gradient2", div_gradient_pal(low, mid, high, space), na.value = na.value, guide = guide, ..., rescaler = mid_rescaler(mid = midpoint)) } #' @rdname scale_gradient #' @export -scale_fill_gradient2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"), midpoint = 0, space = "Lab", na.value = "grey50", guide = "colourbar") { - continuous_scale("fill", "gradient2", +scale_fill_gradient2 <- function(..., low = muted("red"), mid = "white", high = muted("blue"), + midpoint = 0, space = "Lab", na.value = "grey50", guide = "colourbar", + aesthetics = "fill") { + continuous_scale(aesthetics, "gradient2", div_gradient_pal(low, mid, high, space), na.value = na.value, guide = guide, ..., rescaler = mid_rescaler(mid = midpoint)) } @@ -95,17 +101,19 @@ mid_rescaler <- function(mid) { #' @param colours,colors Vector of colours to use for n-colour gradient. #' @rdname scale_gradient #' @export -scale_colour_gradientn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar", colors) { +scale_colour_gradientn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50", + guide = "colourbar", aesthetics = "colour", colors) { colours <- if (missing(colours)) colors else colours - continuous_scale("colour", "gradientn", + continuous_scale(aesthetics, "gradientn", gradient_n_pal(colours, values, space), na.value = na.value, guide = guide, ...) } #' @rdname scale_gradient #' @export -scale_fill_gradientn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50", guide = "colourbar", colors) { +scale_fill_gradientn <- function(..., colours, values = NULL, space = "Lab", na.value = "grey50", + guide = "colourbar", aesthetics = "fill", colors) { colours <- if (missing(colours)) colors else colours - continuous_scale("fill", "gradientn", + continuous_scale(aesthetics, "gradientn", gradient_n_pal(colours, values, space), na.value = na.value, guide = guide, ...) } diff --git a/R/scale-grey.r b/R/scale-grey.r index 420190d2fc..75af9a314b 100644 --- a/R/scale-grey.r +++ b/R/scale-grey.r @@ -25,14 +25,14 @@ #' ggplot(mtcars, aes(mpg, wt)) + #' geom_point(aes(colour = miss)) + #' scale_colour_grey(na.value = "green") -scale_colour_grey <- function(..., start = 0.2, end = 0.8, na.value = "red") { - discrete_scale("colour", "grey", grey_pal(start, end), +scale_colour_grey <- function(..., start = 0.2, end = 0.8, na.value = "red", aesthetics = "colour") { + discrete_scale(aesthetics, "grey", grey_pal(start, end), na.value = na.value, ...) } #' @rdname scale_grey #' @export -scale_fill_grey <- function(..., start = 0.2, end = 0.8, na.value = "red") { - discrete_scale("fill", "grey", grey_pal(start, end), +scale_fill_grey <- function(..., start = 0.2, end = 0.8, na.value = "red", aesthetics = "fill") { + discrete_scale(aesthetics, "grey", grey_pal(start, end), na.value = na.value, ...) } diff --git a/R/scale-hue.r b/R/scale-hue.r index add7bf0aaf..7e6dd385c7 100644 --- a/R/scale-hue.r +++ b/R/scale-hue.r @@ -5,7 +5,9 @@ #' colour-blind safe palettes. #' #' @param na.value Colour to use for missing values -#' @inheritDotParams discrete_scale +#' @inheritDotParams discrete_scale -aesthetics +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @inheritParams scales::hue_pal #' @rdname scale_hue #' @export @@ -46,14 +48,16 @@ #' geom_point(aes(colour = miss)) + #' scale_colour_hue(na.value = "black") #' } -scale_colour_hue <- function(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, direction = 1, na.value = "grey50") { - discrete_scale("colour", "hue", hue_pal(h, c, l, h.start, direction), +scale_colour_hue <- function(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, + direction = 1, na.value = "grey50", aesthetics = "colour") { + discrete_scale(aesthetics, "hue", hue_pal(h, c, l, h.start, direction), na.value = na.value, ...) } #' @rdname scale_hue #' @export -scale_fill_hue <- function(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, direction = 1, na.value = "grey50") { - discrete_scale("fill", "hue", hue_pal(h, c, l, h.start, direction), +scale_fill_hue <- function(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, + direction = 1, na.value = "grey50", aesthetics = "fill") { + discrete_scale(aesthetics, "hue", hue_pal(h, c, l, h.start, direction), na.value = na.value, ...) } diff --git a/R/scale-identity.r b/R/scale-identity.r index 905e864458..137462be78 100644 --- a/R/scale-identity.r +++ b/R/scale-identity.r @@ -7,6 +7,7 @@ #' #' @param ... Other arguments passed on to [discrete_scale()] or #' [continuous_scale()] +#' @param aesthetics The names of the aesthetics that this scale works with #' @param guide Guide to use for this scale. Defaults to `"none"`. #' @examples #' ggplot(luv_colours, aes(u, v)) + @@ -48,8 +49,8 @@ NULL #' @rdname scale_identity #' @export -scale_colour_identity <- function(..., guide = "none") { - sc <- discrete_scale("colour", "identity", identity_pal(), ..., guide = guide, +scale_colour_identity <- function(..., guide = "none", aesthetics = "colour") { + sc <- discrete_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, super = ScaleDiscreteIdentity) sc @@ -57,8 +58,8 @@ scale_colour_identity <- function(..., guide = "none") { #' @rdname scale_identity #' @export -scale_fill_identity <- function(..., guide = "none") { - sc <- discrete_scale("fill", "identity", identity_pal(), ..., guide = guide, +scale_fill_identity <- function(..., guide = "none", aesthetics = "fill") { + sc <- discrete_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, super = ScaleDiscreteIdentity) sc @@ -66,8 +67,8 @@ scale_fill_identity <- function(..., guide = "none") { #' @rdname scale_identity #' @export -scale_shape_identity <- function(..., guide = "none") { - sc <- continuous_scale("shape", "identity", identity_pal(), ..., guide = guide, +scale_shape_identity <- function(..., guide = "none", aesthetics = "shape") { + sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, super = ScaleDiscreteIdentity) sc @@ -75,8 +76,8 @@ scale_shape_identity <- function(..., guide = "none") { #' @rdname scale_identity #' @export -scale_linetype_identity <- function(..., guide = "none") { - sc <- discrete_scale("linetype", "identity", identity_pal(), ..., guide = guide, +scale_linetype_identity <- function(..., guide = "none", aesthetics = "linetype") { + sc <- discrete_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, super = ScaleDiscreteIdentity) sc @@ -84,8 +85,8 @@ scale_linetype_identity <- function(..., guide = "none") { #' @rdname scale_identity #' @export -scale_alpha_identity <- function(..., guide = "none") { - sc <- continuous_scale("alpha", "identity", identity_pal(), ..., guide = guide, +scale_alpha_identity <- function(..., guide = "none", aesthetics = "alpha") { + sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, super = ScaleContinuousIdentity) sc @@ -93,8 +94,8 @@ scale_alpha_identity <- function(..., guide = "none") { #' @rdname scale_identity #' @export -scale_size_identity <- function(..., guide = "none") { - sc <- continuous_scale("size", "identity", identity_pal(), ..., guide = guide, +scale_size_identity <- function(..., guide = "none", aesthetics = "size") { + sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, super = ScaleContinuousIdentity) sc diff --git a/R/scale-linetype.r b/R/scale-linetype.r index 874c25d6ff..4381fb4636 100644 --- a/R/scale-linetype.r +++ b/R/scale-linetype.r @@ -5,7 +5,9 @@ #' line types. #' #' @inheritParams scale_x_discrete -#' @inheritDotParams discrete_scale -expand -position -na.value +#' @inheritDotParams discrete_scale -expand -position -na.value -aesthetics +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @param na.value The linetype to use for `NA` values. #' @rdname scale_linetype #' @export @@ -28,8 +30,8 @@ #' scale_linetype_identity() + #' facet_grid(linetype ~ .) + #' theme_void(20) -scale_linetype <- function(..., na.value = "blank") { - discrete_scale("linetype", "linetype_d", linetype_pal(), +scale_linetype <- function(..., na.value = "blank", aesthetics = "linetype") { + discrete_scale(aesthetics, "linetype_d", linetype_pal(), na.value = na.value, ...) } diff --git a/R/scale-manual.r b/R/scale-manual.r index a648e92f9f..4db0aced95 100644 --- a/R/scale-manual.r +++ b/R/scale-manual.r @@ -4,7 +4,9 @@ #' data to aesthetic values. #' #' @inheritParams scale_x_discrete -#' @inheritDotParams discrete_scale -expand -position +#' @inheritDotParams discrete_scale -expand -position -aesthetics +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @param values a set of aesthetic values to map data values to. If this #' is a named vector, then the values will be matched based on the names. #' If unnamed, values will be matched in order (usually alphabetical) with @@ -37,38 +39,38 @@ NULL #' @rdname scale_manual #' @export -scale_colour_manual <- function(..., values) { - manual_scale("colour", values, ...) +scale_colour_manual <- function(..., values, aesthetics = "colour") { + manual_scale(aesthetics, values, ...) } #' @rdname scale_manual #' @export -scale_fill_manual <- function(..., values) { - manual_scale("fill", values, ...) +scale_fill_manual <- function(..., values, aesthetics = "fill") { + manual_scale(aesthetics, values, ...) } #' @rdname scale_manual #' @export -scale_size_manual <- function(..., values) { - manual_scale("size", values, ...) +scale_size_manual <- function(..., values, aesthetics = "size") { + manual_scale(aesthetics, values, ...) } #' @rdname scale_manual #' @export -scale_shape_manual <- function(..., values) { - manual_scale("shape", values, ...) +scale_shape_manual <- function(..., values, aesthetics = "shape") { + manual_scale(aesthetics, values, ...) } #' @rdname scale_manual #' @export -scale_linetype_manual <- function(..., values) { - manual_scale("linetype", values, ...) +scale_linetype_manual <- function(..., values, aesthetics = "linetype") { + manual_scale(aesthetics, values, ...) } #' @rdname scale_manual #' @export -scale_alpha_manual <- function(..., values) { - manual_scale("alpha", values, ...) +scale_alpha_manual <- function(..., values, aesthetics = "alpha") { + manual_scale(aesthetics, values, ...) } manual_scale <- function(aesthetic, values, ...) { diff --git a/R/scale-shape.r b/R/scale-shape.r index 2a7c8cabac..93df003d74 100644 --- a/R/scale-shape.r +++ b/R/scale-shape.r @@ -9,7 +9,9 @@ #' @param solid Should the shapes be solid, `TRUE`, or hollow, #' `FALSE`? #' @inheritParams scale_x_discrete -#' @inheritDotParams discrete_scale -expand -position +#' @inheritDotParams discrete_scale -expand -position -aesthetics +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @rdname scale_shape #' @export #' @examples @@ -34,8 +36,8 @@ #' scale_shape_identity() + #' facet_wrap(~shape) + #' theme_void() -scale_shape <- function(..., solid = TRUE) { - discrete_scale("shape", "shape_d", shape_pal(solid), ...) +scale_shape <- function(..., solid = TRUE, aesthetics = "shape") { + discrete_scale(aesthetics, "shape_d", shape_pal(solid), ...) } #' @rdname scale_shape diff --git a/R/scale-size.r b/R/scale-size.r index 240f9f70e8..a8797fb78f 100644 --- a/R/scale-size.r +++ b/R/scale-size.r @@ -8,6 +8,8 @@ #' #' @name scale_size #' @inheritParams continuous_scale +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @param range a numeric vector of length 2 that specifies the minimum and #' maximum size of the plotting symbol after transformation. #' @seealso [scale_size_area()] if you want 0 values to be mapped @@ -36,8 +38,8 @@ NULL #' @usage NULL scale_size_continuous <- function(name = waiver(), breaks = waiver(), labels = waiver(), limits = NULL, range = c(1, 6), - trans = "identity", guide = "legend") { - continuous_scale("size", "area", area_pal(range), name = name, + trans = "identity", guide = "legend", aesthetics = "size") { + continuous_scale(aesthetics, "area", area_pal(range), name = name, breaks = breaks, labels = labels, limits = limits, trans = trans, guide = guide) } @@ -46,8 +48,8 @@ scale_size_continuous <- function(name = waiver(), breaks = waiver(), labels = w #' @export scale_radius <- function(name = waiver(), breaks = waiver(), labels = waiver(), limits = NULL, range = c(1, 6), - trans = "identity", guide = "legend") { - continuous_scale("size", "radius", rescale_pal(range), name = name, + trans = "identity", guide = "legend", aesthetics = "size") { + continuous_scale(aesthetics, "radius", rescale_pal(range), name = name, breaks = breaks, labels = labels, limits = limits, trans = trans, guide = guide) } @@ -67,9 +69,9 @@ scale_size_discrete <- function(...) { #' @rdname scale_size #' @export #' @usage NULL -scale_size_ordinal <- function(..., range = c(2, 6)) { +scale_size_ordinal <- function(..., range = c(2, 6), aesthetics = "size") { discrete_scale( - "size", + aesthetics, "size_d", function(n) { area <- seq(range[1] ^ 2, range[2] ^ 2, length.out = n) @@ -83,8 +85,8 @@ scale_size_ordinal <- function(..., range = c(2, 6)) { #' @param max_size Size of largest points. #' @export #' @rdname scale_size -scale_size_area <- function(..., max_size = 6) { - continuous_scale("size", "area", +scale_size_area <- function(..., max_size = 6, aesthetics = "size") { + continuous_scale(aesthetics, "area", palette = abs_area(max_size), rescaler = rescale_max, ...) } @@ -92,13 +94,13 @@ scale_size_area <- function(..., max_size = 6) { #' @rdname scale_size #' @export #' @usage NULL -scale_size_datetime <- function(..., range = c(1, 6)) { - datetime_scale("size", "time", palette = area_pal(range), ...) +scale_size_datetime <- function(..., range = c(1, 6), aesthetics = "size") { + datetime_scale(aesthetics, "time", palette = area_pal(range), ...) } #' @rdname scale_size #' @export #' @usage NULL -scale_size_date <- function(..., range = c(1, 6)) { - datetime_scale("size", "date", palette = area_pal(range), ...) +scale_size_date <- function(..., range = c(1, 6), aesthetics = "size") { + datetime_scale(aesthetics, "date", palette = area_pal(range), ...) } diff --git a/R/scale-viridis.r b/R/scale-viridis.r index 0b99b27dc9..660f2226a2 100644 --- a/R/scale-viridis.r +++ b/R/scale-viridis.r @@ -4,12 +4,14 @@ #' color and black-and-white. They are also designed to be perceived by viewers #' with common forms of color blindness. See also #' . -#' +#' #' @inheritParams viridisLite::viridis #' @inheritParams scales::gradient_n_pal #' @inheritParams continuous_scale #' @param ... Other arguments passed on to [discrete_scale()] or #' [continuous_scale()] to control name, limits, breaks, labels and so forth. +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. #' @family colour scales #' @rdname scale_viridis #' @export @@ -43,9 +45,9 @@ #' v + scale_fill_viridis_c() #' v + scale_fill_viridis_c(option = "plasma") scale_colour_viridis_d <- function(..., alpha = 1, begin = 0, end = 1, - direction = 1, option = "D") { + direction = 1, option = "D", aesthetics = "colour") { discrete_scale( - "colour", + aesthetics, "viridis_d", viridis_pal(alpha, begin, end, direction, option), ... @@ -55,9 +57,9 @@ scale_colour_viridis_d <- function(..., alpha = 1, begin = 0, end = 1, #' @export #' @rdname scale_viridis scale_fill_viridis_d <- function(..., alpha = 1, begin = 0, end = 1, - direction = 1, option = "D") { + direction = 1, option = "D", aesthetics = "fill") { discrete_scale( - "fill", + aesthetics, "viridis_d", viridis_pal(alpha, begin, end, direction, option), ... @@ -69,9 +71,9 @@ scale_fill_viridis_d <- function(..., alpha = 1, begin = 0, end = 1, scale_colour_viridis_c <- function(..., alpha = 1, begin = 0, end = 1, direction = 1, option = "D", values = NULL, space = "Lab", na.value = "grey50", - guide = "colourbar") { + guide = "colourbar", aesthetics = "colour") { continuous_scale( - "colour", + aesthetics, "viridis_c", gradient_n_pal( viridis_pal(alpha, begin, end, direction, option)(6), @@ -89,9 +91,9 @@ scale_colour_viridis_c <- function(..., alpha = 1, begin = 0, end = 1, scale_fill_viridis_c <- function(..., alpha = 1, begin = 0, end = 1, direction = 1, option = "D", values = NULL, space = "Lab", na.value = "grey50", - guide = "colourbar") { + guide = "colourbar", aesthetics = "fill") { continuous_scale( - "fill", + aesthetics, "viridis_c", gradient_n_pal( viridis_pal(alpha, begin, end, direction, option)(6), diff --git a/man/guide-exts.Rd b/man/guide-exts.Rd index f5b1ba8c0c..8d4fb270f4 100644 --- a/man/guide-exts.Rd +++ b/man/guide-exts.Rd @@ -8,7 +8,7 @@ \alias{guide_gengrob} \title{S3 generics for guides.} \usage{ -guide_train(guide, scale) +guide_train(guide, scale, aesthetic = NULL) guide_merge(guide, new_guide) diff --git a/man/scale_alpha.Rd b/man/scale_alpha.Rd index fdd86fffc4..79ed7ce68d 100644 --- a/man/scale_alpha.Rd +++ b/man/scale_alpha.Rd @@ -9,13 +9,13 @@ \alias{scale_alpha_date} \title{Alpha transparency scales} \usage{ -scale_alpha(..., range = c(0.1, 1)) +scale_alpha(..., range = c(0.1, 1), aesthetics = "alpha") -scale_alpha_continuous(..., range = c(0.1, 1)) +scale_alpha_continuous(..., range = c(0.1, 1), aesthetics = "alpha") scale_alpha_discrete(...) -scale_alpha_ordinal(..., range = c(0.1, 1)) +scale_alpha_ordinal(..., range = c(0.1, 1), aesthetics = "alpha") } \arguments{ \item{...}{Other arguments passed on to \code{\link[=continuous_scale]{continuous_scale()}} @@ -23,6 +23,9 @@ or \code{\link[=discrete_scale]{discrete_scale()}} as appropriate, to control na breaks, labels and so forth.} \item{range}{Output range of alpha values. Must lie between 0 and 1.} + +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} } \description{ Alpha-transparency scales are not tremendously useful, but can be a diff --git a/man/scale_brewer.Rd b/man/scale_brewer.Rd index 03a7c79f8a..294920e23e 100644 --- a/man/scale_brewer.Rd +++ b/man/scale_brewer.Rd @@ -9,17 +9,19 @@ \alias{scale_color_distiller} \title{Sequential, diverging and qualitative colour scales from colorbrewer.org} \usage{ -scale_colour_brewer(..., type = "seq", palette = 1, direction = 1) +scale_colour_brewer(..., type = "seq", palette = 1, direction = 1, + aesthetics = "colour") -scale_fill_brewer(..., type = "seq", palette = 1, direction = 1) +scale_fill_brewer(..., type = "seq", palette = 1, direction = 1, + aesthetics = "fill") scale_colour_distiller(..., type = "seq", palette = 1, direction = -1, values = NULL, space = "Lab", na.value = "grey50", - guide = "colourbar") + guide = "colourbar", aesthetics = "colour") scale_fill_distiller(..., type = "seq", palette = 1, direction = -1, values = NULL, space = "Lab", na.value = "grey50", - guide = "colourbar") + guide = "colourbar", aesthetics = "fill") } \arguments{ \item{...}{Other arguments passed on to \code{\link[=discrete_scale]{discrete_scale()}} or, for @@ -35,6 +37,9 @@ index into the list of palettes of appropriate \code{type}} colors are as output by \code{\link[RColorBrewer]{brewer.pal}}. If -1, the order of colors is reversed.} +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} + \item{values}{if colours should not be evenly positioned along the gradient this vector gives the position (between 0 and 1) for each colour in the \code{colours} vector. See \code{\link{rescale}} for a convience function diff --git a/man/scale_gradient.Rd b/man/scale_gradient.Rd index 54179a1763..1f967841ba 100644 --- a/man/scale_gradient.Rd +++ b/man/scale_gradient.Rd @@ -18,24 +18,25 @@ \title{Gradient colour scales} \usage{ scale_colour_gradient(..., low = "#132B43", high = "#56B1F7", - space = "Lab", na.value = "grey50", guide = "colourbar") + space = "Lab", na.value = "grey50", guide = "colourbar", + aesthetics = "colour") scale_fill_gradient(..., low = "#132B43", high = "#56B1F7", space = "Lab", - na.value = "grey50", guide = "colourbar") + na.value = "grey50", guide = "colourbar", aesthetics = "fill") scale_colour_gradient2(..., low = muted("red"), mid = "white", high = muted("blue"), midpoint = 0, space = "Lab", - na.value = "grey50", guide = "colourbar") + na.value = "grey50", guide = "colourbar", aesthetics = "colour") scale_fill_gradient2(..., low = muted("red"), mid = "white", high = muted("blue"), midpoint = 0, space = "Lab", - na.value = "grey50", guide = "colourbar") + na.value = "grey50", guide = "colourbar", aesthetics = "fill") scale_colour_gradientn(..., colours, values = NULL, space = "Lab", - na.value = "grey50", guide = "colourbar", colors) + na.value = "grey50", guide = "colourbar", aesthetics = "colour", colors) scale_fill_gradientn(..., colours, values = NULL, space = "Lab", - na.value = "grey50", guide = "colourbar", colors) + na.value = "grey50", guide = "colourbar", aesthetics = "fill", colors) } \arguments{ \item{...}{Arguments passed on to \code{continuous_scale} @@ -113,6 +114,9 @@ other values are deprecated.} \item{guide}{Type of legend. Use \code{"colourbar"} for continuous colour bar, or \code{"legend"} for discrete colour legend.} +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} + \item{mid}{colour for mid point} \item{midpoint}{The midpoint (in data value) of the diverging scale. diff --git a/man/scale_grey.Rd b/man/scale_grey.Rd index 5875f0c22a..21b2eee09d 100644 --- a/man/scale_grey.Rd +++ b/man/scale_grey.Rd @@ -6,9 +6,11 @@ \alias{scale_color_grey} \title{Sequential grey colour scales} \usage{ -scale_colour_grey(..., start = 0.2, end = 0.8, na.value = "red") +scale_colour_grey(..., start = 0.2, end = 0.8, na.value = "red", + aesthetics = "colour") -scale_fill_grey(..., start = 0.2, end = 0.8, na.value = "red") +scale_fill_grey(..., start = 0.2, end = 0.8, na.value = "red", + aesthetics = "fill") } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -69,6 +71,9 @@ scales, "top" or "bottom" for horizontal scales} \item{end}{gray value at high end of palette} \item{na.value}{Colour to use for missing values} + +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} } \description{ Based on \code{\link[=gray.colors]{gray.colors()}}. This is black and white equivalent diff --git a/man/scale_hue.Rd b/man/scale_hue.Rd index fe8b208273..1ccdf19e39 100644 --- a/man/scale_hue.Rd +++ b/man/scale_hue.Rd @@ -10,10 +10,10 @@ \title{Evenly spaced colours for discrete data} \usage{ scale_colour_hue(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, - direction = 1, na.value = "grey50") + direction = 1, na.value = "grey50", aesthetics = "colour") scale_fill_hue(..., h = c(0, 360) + 15, c = 100, l = 65, h.start = 0, - direction = 1, na.value = "grey50") + direction = 1, na.value = "grey50", aesthetics = "fill") } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -38,7 +38,6 @@ from a discrete scale, specify \code{na.translate = FALSE}.} \item{na.value}{If \code{na.translate = TRUE}, what value aesthetic value should missing be displayed as? Does not apply to position scales where \code{NA} is always placed at the far right.} - \item{aesthetics}{The names of the aesthetics that this scale works with} \item{scale_name}{The name of the scale} \item{palette}{A palette function that when called with a single integer argument (the number of levels in the scale) returns the values that @@ -82,6 +81,9 @@ combination of hue and luminance.} 1 = clockwise, -1 = counter-clockwise} \item{na.value}{Colour to use for missing values} + +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} } \description{ This is the default colour scale for categorical variables. It maps each diff --git a/man/scale_identity.Rd b/man/scale_identity.Rd index e4a7304f3b..c6f62c2655 100644 --- a/man/scale_identity.Rd +++ b/man/scale_identity.Rd @@ -10,23 +10,25 @@ \alias{scale_color_identity} \title{Use values without scaling} \usage{ -scale_colour_identity(..., guide = "none") +scale_colour_identity(..., guide = "none", aesthetics = "colour") -scale_fill_identity(..., guide = "none") +scale_fill_identity(..., guide = "none", aesthetics = "fill") -scale_shape_identity(..., guide = "none") +scale_shape_identity(..., guide = "none", aesthetics = "shape") -scale_linetype_identity(..., guide = "none") +scale_linetype_identity(..., guide = "none", aesthetics = "linetype") -scale_alpha_identity(..., guide = "none") +scale_alpha_identity(..., guide = "none", aesthetics = "alpha") -scale_size_identity(..., guide = "none") +scale_size_identity(..., guide = "none", aesthetics = "size") } \arguments{ \item{...}{Other arguments passed on to \code{\link[=discrete_scale]{discrete_scale()}} or \code{\link[=continuous_scale]{continuous_scale()}}} \item{guide}{Guide to use for this scale. Defaults to \code{"none"}.} + +\item{aesthetics}{The names of the aesthetics that this scale works with} } \description{ Use this set of scales when your data has already been scaled, i.e. it diff --git a/man/scale_linetype.Rd b/man/scale_linetype.Rd index a940ab6dfa..c1dd95641d 100644 --- a/man/scale_linetype.Rd +++ b/man/scale_linetype.Rd @@ -6,11 +6,11 @@ \alias{scale_linetype_discrete} \title{Scale for line patterns} \usage{ -scale_linetype(..., na.value = "blank") +scale_linetype(..., na.value = "blank", aesthetics = "linetype") scale_linetype_continuous(...) -scale_linetype_discrete(..., na.value = "blank") +scale_linetype_discrete(..., na.value = "blank", aesthetics = "linetype") } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -32,7 +32,6 @@ The default, \code{TRUE}, uses the levels that appear in the data; \item{na.translate}{Unlike continuous scales, discrete scales can easily show missing values, and do so by default. If you want to remove missing values from a discrete scale, specify \code{na.translate = FALSE}.} - \item{aesthetics}{The names of the aesthetics that this scale works with} \item{scale_name}{The name of the scale} \item{palette}{A palette function that when called with a single integer argument (the number of levels in the scale) returns the values that @@ -56,6 +55,9 @@ as output }} \item{na.value}{The linetype to use for \code{NA} values.} + +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} } \description{ Default line types based on a set supplied by Richard Pearson, diff --git a/man/scale_manual.Rd b/man/scale_manual.Rd index 04b99d6825..8642f8af40 100644 --- a/man/scale_manual.Rd +++ b/man/scale_manual.Rd @@ -10,17 +10,17 @@ \alias{scale_color_manual} \title{Create your own discrete scale} \usage{ -scale_colour_manual(..., values) +scale_colour_manual(..., values, aesthetics = "colour") -scale_fill_manual(..., values) +scale_fill_manual(..., values, aesthetics = "fill") -scale_size_manual(..., values) +scale_size_manual(..., values, aesthetics = "size") -scale_shape_manual(..., values) +scale_shape_manual(..., values, aesthetics = "shape") -scale_linetype_manual(..., values) +scale_linetype_manual(..., values, aesthetics = "linetype") -scale_alpha_manual(..., values) +scale_alpha_manual(..., values, aesthetics = "alpha") } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -45,7 +45,6 @@ from a discrete scale, specify \code{na.translate = FALSE}.} \item{na.value}{If \code{na.translate = TRUE}, what value aesthetic value should missing be displayed as? Does not apply to position scales where \code{NA} is always placed at the far right.} - \item{aesthetics}{The names of the aesthetics that this scale works with} \item{scale_name}{The name of the scale} \item{palette}{A palette function that when called with a single integer argument (the number of levels in the scale) returns the values that @@ -73,6 +72,9 @@ is a named vector, then the values will be matched based on the names. If unnamed, values will be matched in order (usually alphabetical) with the limits of the scale. Any data values that don't match will be given \code{na.value}.} + +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} } \description{ This allows you to specify you own set of mappings from levels in the diff --git a/man/scale_shape.Rd b/man/scale_shape.Rd index 98da023d9e..252cd1e570 100644 --- a/man/scale_shape.Rd +++ b/man/scale_shape.Rd @@ -7,7 +7,7 @@ \alias{scale_shape_continuous} \title{Scales for shapes, aka glyphs} \usage{ -scale_shape(..., solid = TRUE) +scale_shape(..., solid = TRUE, aesthetics = "shape") } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -32,7 +32,6 @@ from a discrete scale, specify \code{na.translate = FALSE}.} \item{na.value}{If \code{na.translate = TRUE}, what value aesthetic value should missing be displayed as? Does not apply to position scales where \code{NA} is always placed at the far right.} - \item{aesthetics}{The names of the aesthetics that this scale works with} \item{scale_name}{The name of the scale} \item{palette}{A palette function that when called with a single integer argument (the number of levels in the scale) returns the values that @@ -57,6 +56,9 @@ as output \item{solid}{Should the shapes be solid, \code{TRUE}, or hollow, \code{FALSE}?} + +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} } \description{ \code{scale_shape} maps discrete variables to six easily discernible shapes. diff --git a/man/scale_size.Rd b/man/scale_size.Rd index dc29a76070..303b674922 100644 --- a/man/scale_size.Rd +++ b/man/scale_size.Rd @@ -12,12 +12,14 @@ \title{Scales for area or radius} \usage{ scale_radius(name = waiver(), breaks = waiver(), labels = waiver(), - limits = NULL, range = c(1, 6), trans = "identity", guide = "legend") + limits = NULL, range = c(1, 6), trans = "identity", guide = "legend", + aesthetics = "size") scale_size(name = waiver(), breaks = waiver(), labels = waiver(), - limits = NULL, range = c(1, 6), trans = "identity", guide = "legend") + limits = NULL, range = c(1, 6), trans = "identity", guide = "legend", + aesthetics = "size") -scale_size_area(..., max_size = 6) +scale_size_area(..., max_size = 6, aesthetics = "size") } \arguments{ \item{name}{The name of the scale. Used as axis or legend title. If @@ -65,6 +67,9 @@ transformation with \code{\link[scales:trans_new]{scales::trans_new()}}.} \item{guide}{A function used to create a guide or its name. See \code{\link[=guides]{guides()}} for more info.} +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} + \item{...}{Arguments passed on to \code{continuous_scale} \describe{ \item{name}{The name of the scale. Used as axis or legend title. If diff --git a/man/scale_viridis.Rd b/man/scale_viridis.Rd index b22af8489c..2ca147c887 100644 --- a/man/scale_viridis.Rd +++ b/man/scale_viridis.Rd @@ -12,18 +12,18 @@ \title{Viridis colour scales from viridisLite} \usage{ scale_colour_viridis_d(..., alpha = 1, begin = 0, end = 1, - direction = 1, option = "D") + direction = 1, option = "D", aesthetics = "colour") scale_fill_viridis_d(..., alpha = 1, begin = 0, end = 1, direction = 1, - option = "D") + option = "D", aesthetics = "fill") scale_colour_viridis_c(..., alpha = 1, begin = 0, end = 1, direction = 1, option = "D", values = NULL, space = "Lab", - na.value = "grey50", guide = "colourbar") + na.value = "grey50", guide = "colourbar", aesthetics = "colour") scale_fill_viridis_c(..., alpha = 1, begin = 0, end = 1, direction = 1, option = "D", values = NULL, space = "Lab", na.value = "grey50", - guide = "colourbar") + guide = "colourbar", aesthetics = "fill") } \arguments{ \item{...}{Other arguments passed on to \code{\link[=discrete_scale]{discrete_scale()}} or @@ -43,6 +43,9 @@ are ordered from darkest to lightest. If -1, the order of colors is reversed.} options are available: "magma" (or "A"), "inferno" (or "B"), "plasma" (or "C"), "viridis" (or "D", the default option) and "cividis" (or "E").} +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with.} + \item{values}{if colours should not be evenly positioned along the gradient this vector gives the position (between 0 and 1) for each colour in the \code{colours} vector. See \code{\link{rescale}} for a convience function From 882eedbdbb7157000ea6be8973a40a605a81ff84 Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Fri, 4 May 2018 16:22:51 -0500 Subject: [PATCH 03/10] update NEWS --- NEWS.md | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/NEWS.md b/NEWS.md index e306f62043..eb795e74e2 100644 --- a/NEWS.md +++ b/NEWS.md @@ -177,6 +177,10 @@ up correct aspect ratio, and draws a graticule. use matrix-columns. These are rarely used but are produced by `scale()`; to continue use `scale()` you'll need to wrap it with `as.numeric()`, e.g. `as.numeric(scale(x))`. + +* The function `guide_train()` now has an optional parameter `aesthetic` + that allows to override the `aesthetic` setting in the scale. This change + will only affect code that implements custom guides. (@clauswilke) ## Minor bug fixes and improvements @@ -211,6 +215,10 @@ up correct aspect ratio, and draws a graticule. * Legends no longer try and use set aesthetics that are not length one (#1932). +* All scales that are not position scales now have an `aesthetics` argument + that can be used to set the aesthetics the scale works with, regardles of + the name of the scale function. (@clauswilke) + ### Layers * `geom_label` no longer produces an undesired border around labels when From 9628730e46242e3969348034a0568ac6f9d5ce82 Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 01:49:19 -0500 Subject: [PATCH 04/10] add regression tests --- ...olorbar-for-colour-and-fill-aesthetics.svg | 78 +++++++++++++++++++ tests/testthat/test-guides.R | 14 ++++ tests/testthat/test-scales.r | 43 +++++++++- 3 files changed, 134 insertions(+), 1 deletion(-) create mode 100644 tests/figs/guides/one-combined-colorbar-for-colour-and-fill-aesthetics.svg diff --git a/tests/figs/guides/one-combined-colorbar-for-colour-and-fill-aesthetics.svg b/tests/figs/guides/one-combined-colorbar-for-colour-and-fill-aesthetics.svg new file mode 100644 index 0000000000..c39da014de --- /dev/null +++ b/tests/figs/guides/one-combined-colorbar-for-colour-and-fill-aesthetics.svg @@ -0,0 +1,78 @@ + + + + + + + + + + + + + + + + + + + + + + +5.0 +5.5 +6.0 +6.5 +7.0 + + + + + + + + + + +1.0 +1.5 +2.0 +2.5 +3.0 +x +y + + +1 +2 +3 +4 +5 +6 +7 +value + + + + + + + + + + + + + + +one combined colorbar for colour and fill aesthetics + diff --git a/tests/testthat/test-guides.R b/tests/testthat/test-guides.R index 635e6b1301..ef07c812de 100644 --- a/tests/testthat/test-guides.R +++ b/tests/testthat/test-guides.R @@ -205,3 +205,17 @@ test_that("colorbar can be styled", { ) ) }) + +test_that("guides can handle multiple aesthetics for one scale", { + df <- data.frame(x = c(1, 2, 3), + y = c(6, 5, 7)) + + p <- ggplot(df, aes(x, y, color = x, fill = y)) + + geom_point(shape = 21, size = 3, stroke = 2) + + scale_colour_viridis_c( + name = "value", + option = "B", aesthetics = c("colour", "fill") + ) + + expect_doppelganger("one combined colorbar for colour and fill aesthetics", p) +}) diff --git a/tests/testthat/test-scales.r b/tests/testthat/test-scales.r index 947a6f1f66..9eac9f2d51 100644 --- a/tests/testthat/test-scales.r +++ b/tests/testthat/test-scales.r @@ -209,7 +209,7 @@ test_that("Size and alpha scales throw appropriate warnings for factors", { ) # There should be no warnings for ordered factors expect_warning(ggplot_build(p + geom_point(aes(size = o))), NA) - expect_warning(ggplot_build(p + geom_point(aes(alpha = o))), NA) + expect_warning(ggplot_build(p + geom_point(aes(alpha = o))), NA) }) test_that("Shape scale throws appropriate warnings for factors", { @@ -230,3 +230,44 @@ test_that("Shape scale throws appropriate warnings for factors", { "Using shapes for an ordinal variable is not advised" ) }) + +test_that("Aesthetics can be set independently of scale name", { + df <- data.frame( + x = LETTERS[1:3], + y = LETTERS[4:6] + ) + p <- ggplot(df, aes(x, y, fill = y)) + + scale_colour_manual(values = c("red", "green", "blue"), aesthetics = "fill") + + expect_equal(layer_data(p)$fill, c("red", "green", "blue")) +}) + +test_that("Multiple aesthetics can be set with one function call", { + df <- data.frame( + x = LETTERS[1:3], + y = LETTERS[4:6] + ) + p <- ggplot(df, aes(x, y, colour = x, fill = y)) + + scale_colour_manual( + values = c("grey20", "grey40", "grey60", "red", "green", "blue"), + aesthetics = c("colour", "fill") + ) + + expect_equal(layer_data(p)$colour, c("grey20", "grey40", "grey60")) + expect_equal(layer_data(p)$fill, c("red", "green", "blue")) + + # color order is determined by data order, and breaks are combined where possible + df <- data.frame( + x = LETTERS[1:3], + y = LETTERS[2:4] + ) + p <- ggplot(df, aes(x, y, colour = x, fill = y)) + + scale_colour_manual( + values = c("cyan", "red", "green", "blue"), + aesthetics = c("fill", "colour") + ) + + expect_equal(layer_data(p)$colour, c("cyan", "red", "green")) + expect_equal(layer_data(p)$fill, c("red", "green", "blue")) +}) + From 27788e102d6ef80e10b684e0b4efa7ca56c98dd5 Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 11:15:33 -0500 Subject: [PATCH 05/10] update documentation --- man/ggplot2-package.Rd | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/man/ggplot2-package.Rd b/man/ggplot2-package.Rd index 194b24d294..85aba71d74 100644 --- a/man/ggplot2-package.Rd +++ b/man/ggplot2-package.Rd @@ -28,6 +28,10 @@ Useful links: Authors: \itemize{ \item Winston Chang \email{winston@rstudio.com} + \item Kara Woo + \item Thomas Lin Pedersen + \item Claus Wilke + \item Kohske Takahashi } Other contributors: From a3d16cc075a82805a75b6724f2b8e61499483adc Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 21:21:40 -0500 Subject: [PATCH 06/10] revert aesthetics argument for non-color scales --- R/scale-alpha.r | 18 ++++++++---------- R/scale-linetype.r | 8 +++----- R/scale-shape.r | 8 +++----- R/scale-size.r | 26 ++++++++++++-------------- 4 files changed, 26 insertions(+), 34 deletions(-) diff --git a/R/scale-alpha.r b/R/scale-alpha.r index c9d2d0d33c..967ae92d9a 100644 --- a/R/scale-alpha.r +++ b/R/scale-alpha.r @@ -8,8 +8,6 @@ #' @param ... Other arguments passed on to [continuous_scale()] #' or [discrete_scale()] as appropriate, to control name, limits, #' breaks, labels and so forth. -#' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. #' @param range Output range of alpha values. Must lie between 0 and 1. #' @family colour scales #' @export @@ -20,8 +18,8 @@ #' p #' p + scale_alpha("cylinders") #' p + scale_alpha(range = c(0.4, 0.8)) -scale_alpha <- function(..., range = c(0.1, 1), aesthetics = "alpha") { - continuous_scale(aesthetics, "alpha_c", rescale_pal(range), ...) +scale_alpha <- function(..., range = c(0.1, 1)) { + continuous_scale("alpha", "alpha_c", rescale_pal(range), ...) } #' @rdname scale_alpha @@ -37,9 +35,9 @@ scale_alpha_discrete <- function(...) { #' @rdname scale_alpha #' @export -scale_alpha_ordinal <- function(..., range = c(0.1, 1), aesthetics = "alpha") { +scale_alpha_ordinal <- function(..., range = c(0.1, 1)) { discrete_scale( - aesthetics, + "alpha", "alpha_d", function(n) seq(range[1], range[2], length.out = n), ... @@ -49,13 +47,13 @@ scale_alpha_ordinal <- function(..., range = c(0.1, 1), aesthetics = "alpha") { #' @rdname scale_alpha #' @export #' @usage NULL -scale_alpha_datetime <- function(..., range = c(0.1, 1), aesthetics = "alpha") { - datetime_scale(aesthetics, "time", palette = rescale_pal(range), ...) +scale_alpha_datetime <- function(..., range = c(0.1, 1)) { + datetime_scale("alpha", "time", palette = rescale_pal(range), ...) } #' @rdname scale_alpha #' @export #' @usage NULL -scale_alpha_date <- function(..., range = c(0.1, 1), aesthetics = "alpha"){ - datetime_scale(aesthetics, "date", palette = rescale_pal(range), ...) +scale_alpha_date <- function(..., range = c(0.1, 1)){ + datetime_scale("alpha", "date", palette = rescale_pal(range), ...) } diff --git a/R/scale-linetype.r b/R/scale-linetype.r index 4381fb4636..874c25d6ff 100644 --- a/R/scale-linetype.r +++ b/R/scale-linetype.r @@ -5,9 +5,7 @@ #' line types. #' #' @inheritParams scale_x_discrete -#' @inheritDotParams discrete_scale -expand -position -na.value -aesthetics -#' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. +#' @inheritDotParams discrete_scale -expand -position -na.value #' @param na.value The linetype to use for `NA` values. #' @rdname scale_linetype #' @export @@ -30,8 +28,8 @@ #' scale_linetype_identity() + #' facet_grid(linetype ~ .) + #' theme_void(20) -scale_linetype <- function(..., na.value = "blank", aesthetics = "linetype") { - discrete_scale(aesthetics, "linetype_d", linetype_pal(), +scale_linetype <- function(..., na.value = "blank") { + discrete_scale("linetype", "linetype_d", linetype_pal(), na.value = na.value, ...) } diff --git a/R/scale-shape.r b/R/scale-shape.r index 93df003d74..2a7c8cabac 100644 --- a/R/scale-shape.r +++ b/R/scale-shape.r @@ -9,9 +9,7 @@ #' @param solid Should the shapes be solid, `TRUE`, or hollow, #' `FALSE`? #' @inheritParams scale_x_discrete -#' @inheritDotParams discrete_scale -expand -position -aesthetics -#' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. +#' @inheritDotParams discrete_scale -expand -position #' @rdname scale_shape #' @export #' @examples @@ -36,8 +34,8 @@ #' scale_shape_identity() + #' facet_wrap(~shape) + #' theme_void() -scale_shape <- function(..., solid = TRUE, aesthetics = "shape") { - discrete_scale(aesthetics, "shape_d", shape_pal(solid), ...) +scale_shape <- function(..., solid = TRUE) { + discrete_scale("shape", "shape_d", shape_pal(solid), ...) } #' @rdname scale_shape diff --git a/R/scale-size.r b/R/scale-size.r index a8797fb78f..240f9f70e8 100644 --- a/R/scale-size.r +++ b/R/scale-size.r @@ -8,8 +8,6 @@ #' #' @name scale_size #' @inheritParams continuous_scale -#' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. #' @param range a numeric vector of length 2 that specifies the minimum and #' maximum size of the plotting symbol after transformation. #' @seealso [scale_size_area()] if you want 0 values to be mapped @@ -38,8 +36,8 @@ NULL #' @usage NULL scale_size_continuous <- function(name = waiver(), breaks = waiver(), labels = waiver(), limits = NULL, range = c(1, 6), - trans = "identity", guide = "legend", aesthetics = "size") { - continuous_scale(aesthetics, "area", area_pal(range), name = name, + trans = "identity", guide = "legend") { + continuous_scale("size", "area", area_pal(range), name = name, breaks = breaks, labels = labels, limits = limits, trans = trans, guide = guide) } @@ -48,8 +46,8 @@ scale_size_continuous <- function(name = waiver(), breaks = waiver(), labels = w #' @export scale_radius <- function(name = waiver(), breaks = waiver(), labels = waiver(), limits = NULL, range = c(1, 6), - trans = "identity", guide = "legend", aesthetics = "size") { - continuous_scale(aesthetics, "radius", rescale_pal(range), name = name, + trans = "identity", guide = "legend") { + continuous_scale("size", "radius", rescale_pal(range), name = name, breaks = breaks, labels = labels, limits = limits, trans = trans, guide = guide) } @@ -69,9 +67,9 @@ scale_size_discrete <- function(...) { #' @rdname scale_size #' @export #' @usage NULL -scale_size_ordinal <- function(..., range = c(2, 6), aesthetics = "size") { +scale_size_ordinal <- function(..., range = c(2, 6)) { discrete_scale( - aesthetics, + "size", "size_d", function(n) { area <- seq(range[1] ^ 2, range[2] ^ 2, length.out = n) @@ -85,8 +83,8 @@ scale_size_ordinal <- function(..., range = c(2, 6), aesthetics = "size") { #' @param max_size Size of largest points. #' @export #' @rdname scale_size -scale_size_area <- function(..., max_size = 6, aesthetics = "size") { - continuous_scale(aesthetics, "area", +scale_size_area <- function(..., max_size = 6) { + continuous_scale("size", "area", palette = abs_area(max_size), rescaler = rescale_max, ...) } @@ -94,13 +92,13 @@ scale_size_area <- function(..., max_size = 6, aesthetics = "size") { #' @rdname scale_size #' @export #' @usage NULL -scale_size_datetime <- function(..., range = c(1, 6), aesthetics = "size") { - datetime_scale(aesthetics, "time", palette = area_pal(range), ...) +scale_size_datetime <- function(..., range = c(1, 6)) { + datetime_scale("size", "time", palette = area_pal(range), ...) } #' @rdname scale_size #' @export #' @usage NULL -scale_size_date <- function(..., range = c(1, 6), aesthetics = "size") { - datetime_scale(aesthetics, "date", palette = area_pal(range), ...) +scale_size_date <- function(..., range = c(1, 6)) { + datetime_scale("size", "date", palette = area_pal(range), ...) } From 0a48c5ca38b22fbde19bbd457d66a28d3405adf8 Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 21:28:42 -0500 Subject: [PATCH 07/10] revert aesthetics argument for non-color scales, add exported discrete manual scale. --- NAMESPACE | 1 + R/scale-hue.r | 4 +++- R/scale-manual.r | 31 +++++++++++++++++++++---------- R/scale-viridis.r | 4 +++- man/scale_alpha.Rd | 9 +++------ man/scale_brewer.Rd | 4 +++- man/scale_gradient.Rd | 4 +++- man/scale_grey.Rd | 4 +++- man/scale_hue.Rd | 4 +++- man/scale_linetype.Rd | 8 +++----- man/scale_manual.Rd | 21 ++++++++++++++------- man/scale_shape.Rd | 6 ++---- man/scale_size.Rd | 11 +++-------- man/scale_viridis.Rd | 4 +++- 14 files changed, 68 insertions(+), 47 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 8f143efeaa..79ee834122 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -443,6 +443,7 @@ export(scale_colour_manual) export(scale_colour_ordinal) export(scale_colour_viridis_c) export(scale_colour_viridis_d) +export(scale_discrete_manual) export(scale_fill_brewer) export(scale_fill_continuous) export(scale_fill_date) diff --git a/R/scale-hue.r b/R/scale-hue.r index 7e6dd385c7..b1d4903389 100644 --- a/R/scale-hue.r +++ b/R/scale-hue.r @@ -7,7 +7,9 @@ #' @param na.value Colour to use for missing values #' @inheritDotParams discrete_scale -aesthetics #' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. +#' name(s) of the aesthetic(s) that this scale works with. This can be useful, for +#' example, to apply colour settings to the `colour` and `fill` aesthetics at the +#' same time, via `aesthetics = c("colour", "fill")`. #' @inheritParams scales::hue_pal #' @rdname scale_hue #' @export diff --git a/R/scale-manual.r b/R/scale-manual.r index 4db0aced95..6a425d15a8 100644 --- a/R/scale-manual.r +++ b/R/scale-manual.r @@ -1,12 +1,16 @@ #' Create your own discrete scale #' -#' This allows you to specify you own set of mappings from levels in the -#' data to aesthetic values. +#' These functions allow you to specify your own set of mappings from levels in the +#' data to aesthetic values. The function `scale_discrete_manual()` is a generic scale +#' that can work with any aesthetic or set of aesthetics provided via the `aesthetics` +#' argument. #' #' @inheritParams scale_x_discrete #' @inheritDotParams discrete_scale -expand -position -aesthetics #' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. +#' name(s) of the aesthetic(s) that this scale works with. This can be useful, for +#' example, to apply colour settings to the `colour` and `fill` aesthetics at the +#' same time, via `aesthetics = c("colour", "fill")`. #' @param values a set of aesthetic values to map data values to. If this #' is a named vector, then the values will be matched based on the names. #' If unnamed, values will be matched in order (usually alphabetical) with @@ -51,28 +55,35 @@ scale_fill_manual <- function(..., values, aesthetics = "fill") { #' @rdname scale_manual #' @export -scale_size_manual <- function(..., values, aesthetics = "size") { - manual_scale(aesthetics, values, ...) +scale_size_manual <- function(..., values) { + manual_scale("size", values, ...) } #' @rdname scale_manual #' @export -scale_shape_manual <- function(..., values, aesthetics = "shape") { - manual_scale(aesthetics, values, ...) +scale_shape_manual <- function(..., values) { + manual_scale("shape", values, ...) } #' @rdname scale_manual #' @export -scale_linetype_manual <- function(..., values, aesthetics = "linetype") { - manual_scale(aesthetics, values, ...) +scale_linetype_manual <- function(..., values) { + manual_scale("linetype", values, ...) +} + +#' @rdname scale_manual +#' @export +scale_alpha_manual <- function(..., values) { + manual_scale("alpha", values, ...) } #' @rdname scale_manual #' @export -scale_alpha_manual <- function(..., values, aesthetics = "alpha") { +scale_discrete_manual <- function(..., values, aesthetics) { manual_scale(aesthetics, values, ...) } + manual_scale <- function(aesthetic, values, ...) { pal <- function(n) { if (n > length(values)) { diff --git a/R/scale-viridis.r b/R/scale-viridis.r index 660f2226a2..77163a1e06 100644 --- a/R/scale-viridis.r +++ b/R/scale-viridis.r @@ -11,7 +11,9 @@ #' @param ... Other arguments passed on to [discrete_scale()] or #' [continuous_scale()] to control name, limits, breaks, labels and so forth. #' @param aesthetics Character string or vector of character strings listing the -#' name(s) of the aesthetic(s) that this scale works with. +#' name(s) of the aesthetic(s) that this scale works with. This can be useful, for +#' example, to apply colour settings to the `colour` and `fill` aesthetics at the +#' same time, via `aesthetics = c("colour", "fill")`. #' @family colour scales #' @rdname scale_viridis #' @export diff --git a/man/scale_alpha.Rd b/man/scale_alpha.Rd index 79ed7ce68d..fdd86fffc4 100644 --- a/man/scale_alpha.Rd +++ b/man/scale_alpha.Rd @@ -9,13 +9,13 @@ \alias{scale_alpha_date} \title{Alpha transparency scales} \usage{ -scale_alpha(..., range = c(0.1, 1), aesthetics = "alpha") +scale_alpha(..., range = c(0.1, 1)) -scale_alpha_continuous(..., range = c(0.1, 1), aesthetics = "alpha") +scale_alpha_continuous(..., range = c(0.1, 1)) scale_alpha_discrete(...) -scale_alpha_ordinal(..., range = c(0.1, 1), aesthetics = "alpha") +scale_alpha_ordinal(..., range = c(0.1, 1)) } \arguments{ \item{...}{Other arguments passed on to \code{\link[=continuous_scale]{continuous_scale()}} @@ -23,9 +23,6 @@ or \code{\link[=discrete_scale]{discrete_scale()}} as appropriate, to control na breaks, labels and so forth.} \item{range}{Output range of alpha values. Must lie between 0 and 1.} - -\item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} } \description{ Alpha-transparency scales are not tremendously useful, but can be a diff --git a/man/scale_brewer.Rd b/man/scale_brewer.Rd index 294920e23e..f1a6f98544 100644 --- a/man/scale_brewer.Rd +++ b/man/scale_brewer.Rd @@ -38,7 +38,9 @@ colors are as output by \code{\link[RColorBrewer]{brewer.pal}}. If -1, the order of colors is reversed.} \item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} \item{values}{if colours should not be evenly positioned along the gradient this vector gives the position (between 0 and 1) for each colour in the diff --git a/man/scale_gradient.Rd b/man/scale_gradient.Rd index 1f967841ba..41bb70b9f5 100644 --- a/man/scale_gradient.Rd +++ b/man/scale_gradient.Rd @@ -115,7 +115,9 @@ other values are deprecated.} colour bar, or \code{"legend"} for discrete colour legend.} \item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} \item{mid}{colour for mid point} diff --git a/man/scale_grey.Rd b/man/scale_grey.Rd index 21b2eee09d..8258536207 100644 --- a/man/scale_grey.Rd +++ b/man/scale_grey.Rd @@ -73,7 +73,9 @@ scales, "top" or "bottom" for horizontal scales} \item{na.value}{Colour to use for missing values} \item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} } \description{ Based on \code{\link[=gray.colors]{gray.colors()}}. This is black and white equivalent diff --git a/man/scale_hue.Rd b/man/scale_hue.Rd index 1ccdf19e39..bab18af8da 100644 --- a/man/scale_hue.Rd +++ b/man/scale_hue.Rd @@ -83,7 +83,9 @@ combination of hue and luminance.} \item{na.value}{Colour to use for missing values} \item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} } \description{ This is the default colour scale for categorical variables. It maps each diff --git a/man/scale_linetype.Rd b/man/scale_linetype.Rd index c1dd95641d..a940ab6dfa 100644 --- a/man/scale_linetype.Rd +++ b/man/scale_linetype.Rd @@ -6,11 +6,11 @@ \alias{scale_linetype_discrete} \title{Scale for line patterns} \usage{ -scale_linetype(..., na.value = "blank", aesthetics = "linetype") +scale_linetype(..., na.value = "blank") scale_linetype_continuous(...) -scale_linetype_discrete(..., na.value = "blank", aesthetics = "linetype") +scale_linetype_discrete(..., na.value = "blank") } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -32,6 +32,7 @@ The default, \code{TRUE}, uses the levels that appear in the data; \item{na.translate}{Unlike continuous scales, discrete scales can easily show missing values, and do so by default. If you want to remove missing values from a discrete scale, specify \code{na.translate = FALSE}.} + \item{aesthetics}{The names of the aesthetics that this scale works with} \item{scale_name}{The name of the scale} \item{palette}{A palette function that when called with a single integer argument (the number of levels in the scale) returns the values that @@ -55,9 +56,6 @@ as output }} \item{na.value}{The linetype to use for \code{NA} values.} - -\item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} } \description{ Default line types based on a set supplied by Richard Pearson, diff --git a/man/scale_manual.Rd b/man/scale_manual.Rd index 8642f8af40..8f207fa367 100644 --- a/man/scale_manual.Rd +++ b/man/scale_manual.Rd @@ -7,6 +7,7 @@ \alias{scale_shape_manual} \alias{scale_linetype_manual} \alias{scale_alpha_manual} +\alias{scale_discrete_manual} \alias{scale_color_manual} \title{Create your own discrete scale} \usage{ @@ -14,13 +15,15 @@ scale_colour_manual(..., values, aesthetics = "colour") scale_fill_manual(..., values, aesthetics = "fill") -scale_size_manual(..., values, aesthetics = "size") +scale_size_manual(..., values) -scale_shape_manual(..., values, aesthetics = "shape") +scale_shape_manual(..., values) -scale_linetype_manual(..., values, aesthetics = "linetype") +scale_linetype_manual(..., values) -scale_alpha_manual(..., values, aesthetics = "alpha") +scale_alpha_manual(..., values) + +scale_discrete_manual(..., values, aesthetics) } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -74,11 +77,15 @@ the limits of the scale. Any data values that don't match will be given \code{na.value}.} \item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} } \description{ -This allows you to specify you own set of mappings from levels in the -data to aesthetic values. +These functions allow you to specify your own set of mappings from levels in the +data to aesthetic values. The function \code{scale_discrete_manual()} is a generic scale +that can work with any aesthetic or set of aesthetics provided via the \code{aesthetics} +argument. } \examples{ p <- ggplot(mtcars, aes(mpg, wt)) + diff --git a/man/scale_shape.Rd b/man/scale_shape.Rd index 252cd1e570..98da023d9e 100644 --- a/man/scale_shape.Rd +++ b/man/scale_shape.Rd @@ -7,7 +7,7 @@ \alias{scale_shape_continuous} \title{Scales for shapes, aka glyphs} \usage{ -scale_shape(..., solid = TRUE, aesthetics = "shape") +scale_shape(..., solid = TRUE) } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} @@ -32,6 +32,7 @@ from a discrete scale, specify \code{na.translate = FALSE}.} \item{na.value}{If \code{na.translate = TRUE}, what value aesthetic value should missing be displayed as? Does not apply to position scales where \code{NA} is always placed at the far right.} + \item{aesthetics}{The names of the aesthetics that this scale works with} \item{scale_name}{The name of the scale} \item{palette}{A palette function that when called with a single integer argument (the number of levels in the scale) returns the values that @@ -56,9 +57,6 @@ as output \item{solid}{Should the shapes be solid, \code{TRUE}, or hollow, \code{FALSE}?} - -\item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} } \description{ \code{scale_shape} maps discrete variables to six easily discernible shapes. diff --git a/man/scale_size.Rd b/man/scale_size.Rd index 303b674922..dc29a76070 100644 --- a/man/scale_size.Rd +++ b/man/scale_size.Rd @@ -12,14 +12,12 @@ \title{Scales for area or radius} \usage{ scale_radius(name = waiver(), breaks = waiver(), labels = waiver(), - limits = NULL, range = c(1, 6), trans = "identity", guide = "legend", - aesthetics = "size") + limits = NULL, range = c(1, 6), trans = "identity", guide = "legend") scale_size(name = waiver(), breaks = waiver(), labels = waiver(), - limits = NULL, range = c(1, 6), trans = "identity", guide = "legend", - aesthetics = "size") + limits = NULL, range = c(1, 6), trans = "identity", guide = "legend") -scale_size_area(..., max_size = 6, aesthetics = "size") +scale_size_area(..., max_size = 6) } \arguments{ \item{name}{The name of the scale. Used as axis or legend title. If @@ -67,9 +65,6 @@ transformation with \code{\link[scales:trans_new]{scales::trans_new()}}.} \item{guide}{A function used to create a guide or its name. See \code{\link[=guides]{guides()}} for more info.} -\item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} - \item{...}{Arguments passed on to \code{continuous_scale} \describe{ \item{name}{The name of the scale. Used as axis or legend title. If diff --git a/man/scale_viridis.Rd b/man/scale_viridis.Rd index 2ca147c887..bf552837bb 100644 --- a/man/scale_viridis.Rd +++ b/man/scale_viridis.Rd @@ -44,7 +44,9 @@ options are available: "magma" (or "A"), "inferno" (or "B"), "plasma" (or "C"), "viridis" (or "D", the default option) and "cividis" (or "E").} \item{aesthetics}{Character string or vector of character strings listing the -name(s) of the aesthetic(s) that this scale works with.} +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} \item{values}{if colours should not be evenly positioned along the gradient this vector gives the position (between 0 and 1) for each colour in the From a49f59b83400f378776a5aaa160c84f5eb2e617d Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 21:43:33 -0500 Subject: [PATCH 08/10] add generic manual and identity scales --- NAMESPACE | 2 ++ NEWS.md | 11 ++++++++--- R/scale-identity.r | 45 ++++++++++++++++++++++++++++++++----------- R/scale-manual.r | 2 +- man/scale_identity.Rd | 26 ++++++++++++++++++------- man/scale_manual.Rd | 2 +- 6 files changed, 65 insertions(+), 23 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 79ee834122..15ab132a1f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -443,6 +443,8 @@ export(scale_colour_manual) export(scale_colour_ordinal) export(scale_colour_viridis_c) export(scale_colour_viridis_d) +export(scale_continuous_identity) +export(scale_discrete_identity) export(scale_discrete_manual) export(scale_fill_brewer) export(scale_fill_continuous) diff --git a/NEWS.md b/NEWS.md index eb795e74e2..7492fe7480 100644 --- a/NEWS.md +++ b/NEWS.md @@ -215,9 +215,14 @@ up correct aspect ratio, and draws a graticule. * Legends no longer try and use set aesthetics that are not length one (#1932). -* All scales that are not position scales now have an `aesthetics` argument - that can be used to set the aesthetics the scale works with, regardles of - the name of the scale function. (@clauswilke) +* All colour and fill scales now have an `aesthetics` argument that can + be used to set the aesthetic(s) the scale works with. This makes it + possible to apply a colour scale to both colour and fill aesthetics + at the same time, via `aesthetics = c("colour", "fill"). (@clauswilke) + +* Three generic scales were added that work with any aesthetic or set of + aesthetics: `scale_continuous_identity()`, `scale_discrete_identity()`, + `scale_discrete_manual()`. (@clauswilke) ### Layers diff --git a/R/scale-identity.r b/R/scale-identity.r index 137462be78..904e242acd 100644 --- a/R/scale-identity.r +++ b/R/scale-identity.r @@ -2,12 +2,18 @@ #' #' Use this set of scales when your data has already been scaled, i.e. it #' already represents aesthetic values that ggplot2 can handle directly -#' This will not produce a legend unless you also supply the `breaks` -#' and `labels`. +#' This will not produce a legend unless you also supply the `breaks`, +#' `labels`, and type of `guide` you want. The functions `scale_discrete_identity()` +#' and `scale_continuous_identity()` are generic scales that can work with +#' any aesthetic or set of aesthetics provided via the `aesthetics` +#' argument. #' #' @param ... Other arguments passed on to [discrete_scale()] or #' [continuous_scale()] -#' @param aesthetics The names of the aesthetics that this scale works with +#' @param aesthetics Character string or vector of character strings listing the +#' name(s) of the aesthetic(s) that this scale works with. This can be useful, for +#' example, to apply colour settings to the `colour` and `fill` aesthetics at the +#' same time, via `aesthetics = c("colour", "fill")`. #' @param guide Guide to use for this scale. Defaults to `"none"`. #' @examples #' ggplot(luv_colours, aes(u, v)) + @@ -67,8 +73,8 @@ scale_fill_identity <- function(..., guide = "none", aesthetics = "fill") { #' @rdname scale_identity #' @export -scale_shape_identity <- function(..., guide = "none", aesthetics = "shape") { - sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, +scale_shape_identity <- function(..., guide = "none") { + sc <- continuous_scale("shape", "identity", identity_pal(), ..., guide = guide, super = ScaleDiscreteIdentity) sc @@ -76,8 +82,8 @@ scale_shape_identity <- function(..., guide = "none", aesthetics = "shape") { #' @rdname scale_identity #' @export -scale_linetype_identity <- function(..., guide = "none", aesthetics = "linetype") { - sc <- discrete_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, +scale_linetype_identity <- function(..., guide = "none") { + sc <- discrete_scale("linetype", "identity", identity_pal(), ..., guide = guide, super = ScaleDiscreteIdentity) sc @@ -85,8 +91,8 @@ scale_linetype_identity <- function(..., guide = "none", aesthetics = "linetype" #' @rdname scale_identity #' @export -scale_alpha_identity <- function(..., guide = "none", aesthetics = "alpha") { - sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, +scale_alpha_identity <- function(..., guide = "none") { + sc <- continuous_scale("alpha", "identity", identity_pal(), ..., guide = guide, super = ScaleContinuousIdentity) sc @@ -94,13 +100,30 @@ scale_alpha_identity <- function(..., guide = "none", aesthetics = "alpha") { #' @rdname scale_identity #' @export -scale_size_identity <- function(..., guide = "none", aesthetics = "size") { - sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, +scale_size_identity <- function(..., guide = "none") { + sc <- continuous_scale("size", "identity", identity_pal(), ..., guide = guide, super = ScaleContinuousIdentity) sc } +#' @rdname scale_identity +#' @export +scale_discrete_identity <- function(aesthetics, ..., guide = "none") { + sc <- discrete_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, + super = ScaleDiscreteIdentity) + + sc +} + +#' @rdname scale_identity +#' @export +scale_continuous_identity <- function(aesthetics, ..., guide = "none") { + sc <- continuous_scale(aesthetics, "identity", identity_pal(), ..., guide = guide, + super = ScaleContinuousIdentity) + + sc +} #' @rdname ggplot2-ggproto #' @format NULL diff --git a/R/scale-manual.r b/R/scale-manual.r index 6a425d15a8..cccda4a565 100644 --- a/R/scale-manual.r +++ b/R/scale-manual.r @@ -79,7 +79,7 @@ scale_alpha_manual <- function(..., values) { #' @rdname scale_manual #' @export -scale_discrete_manual <- function(..., values, aesthetics) { +scale_discrete_manual <- function(aesthetics, ..., values) { manual_scale(aesthetics, values, ...) } diff --git a/man/scale_identity.Rd b/man/scale_identity.Rd index c6f62c2655..7037b9a9be 100644 --- a/man/scale_identity.Rd +++ b/man/scale_identity.Rd @@ -7,6 +7,8 @@ \alias{scale_linetype_identity} \alias{scale_alpha_identity} \alias{scale_size_identity} +\alias{scale_discrete_identity} +\alias{scale_continuous_identity} \alias{scale_color_identity} \title{Use values without scaling} \usage{ @@ -14,13 +16,17 @@ scale_colour_identity(..., guide = "none", aesthetics = "colour") scale_fill_identity(..., guide = "none", aesthetics = "fill") -scale_shape_identity(..., guide = "none", aesthetics = "shape") +scale_shape_identity(..., guide = "none") -scale_linetype_identity(..., guide = "none", aesthetics = "linetype") +scale_linetype_identity(..., guide = "none") -scale_alpha_identity(..., guide = "none", aesthetics = "alpha") +scale_alpha_identity(..., guide = "none") -scale_size_identity(..., guide = "none", aesthetics = "size") +scale_size_identity(..., guide = "none") + +scale_discrete_identity(aesthetics, ..., guide = "none") + +scale_continuous_identity(aesthetics, ..., guide = "none") } \arguments{ \item{...}{Other arguments passed on to \code{\link[=discrete_scale]{discrete_scale()}} or @@ -28,13 +34,19 @@ scale_size_identity(..., guide = "none", aesthetics = "size") \item{guide}{Guide to use for this scale. Defaults to \code{"none"}.} -\item{aesthetics}{The names of the aesthetics that this scale works with} +\item{aesthetics}{Character string or vector of character strings listing the +name(s) of the aesthetic(s) that this scale works with. This can be useful, for +example, to apply colour settings to the \code{colour} and \code{fill} aesthetics at the +same time, via \code{aesthetics = c("colour", "fill")}.} } \description{ Use this set of scales when your data has already been scaled, i.e. it already represents aesthetic values that ggplot2 can handle directly -This will not produce a legend unless you also supply the \code{breaks} -and \code{labels}. +This will not produce a legend unless you also supply the \code{breaks}, +\code{labels}, and type of \code{guide} you want. The functions \code{scale_discrete_identity()} +and \code{scale_continuous_identity()} are generic scales that can work with +any aesthetic or set of aesthetics provided via the \code{aesthetics} +argument. } \examples{ ggplot(luv_colours, aes(u, v)) + diff --git a/man/scale_manual.Rd b/man/scale_manual.Rd index 8f207fa367..935af6fe1c 100644 --- a/man/scale_manual.Rd +++ b/man/scale_manual.Rd @@ -23,7 +23,7 @@ scale_linetype_manual(..., values) scale_alpha_manual(..., values) -scale_discrete_manual(..., values, aesthetics) +scale_discrete_manual(aesthetics, ..., values) } \arguments{ \item{...}{Arguments passed on to \code{discrete_scale} From 344a69029062a01d42a0d20d89bc7e0157fee8dc Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 21:59:48 -0500 Subject: [PATCH 09/10] add test cases for new generic scales. --- tests/testthat/test-scale-manual.r | 17 ++++++++++++++++- tests/testthat/test-scales.r | 11 +++++++++++ 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-scale-manual.r b/tests/testthat/test-scale-manual.r index 1013c83ba9..0f5d44ddfe 100644 --- a/tests/testthat/test-scale-manual.r +++ b/tests/testthat/test-scale-manual.r @@ -48,10 +48,25 @@ test_that("insufficient values raise an error", { }) -test_that("values are matched when scale contains more unique valuesthan are in the data", { +test_that("values are matched when scale contains more unique values than are in the data", { s <- scale_colour_manual(values = c("8" = "c", "4" = "a", "22" = "d", "6" = "b")) s$train(c("4", "6", "8")) expect_equal(s$map(c("4", "6", "8")), c("a", "b", "c")) }) + +test_that("generic scale can be used in place of aesthetic-specific scales", { + df <- data.frame(x = letters[1:3], y = LETTERS[1:3], z = factor(c(1, 2, 3))) + p1 <- ggplot(df, aes(z, z, shape = x, color = y, alpha = z)) + + scale_shape_manual(values = 1:3) + + scale_colour_manual(values = c("red", "green", "blue")) + + scale_alpha_manual(values = c(0.2, 0.4, 0.6)) + + p2 <- ggplot(df, aes(z, z, shape = x, color = y, alpha = z)) + + scale_discrete_manual(aesthetics = "shape", values = 1:3) + + scale_discrete_manual(aesthetics = "colour", values = c("red", "green", "blue")) + + scale_discrete_manual(aesthetics = "alpha", values = c(0.2, 0.4, 0.6)) + + expect_equal(layer_data(p1), layer_data(p2)) +}) diff --git a/tests/testthat/test-scales.r b/tests/testthat/test-scales.r index 9eac9f2d51..5dab43ca7b 100644 --- a/tests/testthat/test-scales.r +++ b/tests/testthat/test-scales.r @@ -46,6 +46,7 @@ test_that("mapping works", { test_that("identity scale preserves input values", { df <- data.frame(x = 1:3, z = letters[1:3]) + # aesthetic-specific scales p1 <- ggplot(df, aes(x, z, colour = z, fill = z, shape = z, size = x, alpha = x)) + geom_point() + @@ -61,6 +62,16 @@ test_that("identity scale preserves input values", { expect_equal(d1$shape, as.character(df$z)) expect_equal(d1$size, as.numeric(df$z)) expect_equal(d1$alpha, as.numeric(df$z)) + + # generic scales + p2 <- ggplot(df, + aes(x, z, colour = z, fill = z, shape = z, size = x, alpha = x)) + + geom_point() + + scale_discrete_identity(aesthetics = c("colour", "fill", "shape")) + + scale_continuous_identity(aesthetics = c("size", "alpha")) + d2 <- layer_data(p2) + + expect_equal(d1, d2) }) test_that("position scales updated by all position aesthetics", { From a78d22ab8c31132927b7855af68a8edf0b935a3d Mon Sep 17 00:00:00 2001 From: Claus Wilke Date: Wed, 9 May 2018 22:27:41 -0500 Subject: [PATCH 10/10] improve docs --- R/scale-identity.r | 16 +++++++++++----- R/scale-manual.r | 23 ++++++++++++++++++++--- man/scale_identity.Rd | 17 ++++++++++++----- man/scale_manual.Rd | 24 +++++++++++++++++++++--- 4 files changed, 64 insertions(+), 16 deletions(-) diff --git a/R/scale-identity.r b/R/scale-identity.r index 904e242acd..cb5ad9d9c4 100644 --- a/R/scale-identity.r +++ b/R/scale-identity.r @@ -1,11 +1,17 @@ #' Use values without scaling #' #' Use this set of scales when your data has already been scaled, i.e. it -#' already represents aesthetic values that ggplot2 can handle directly -#' This will not produce a legend unless you also supply the `breaks`, -#' `labels`, and type of `guide` you want. The functions `scale_discrete_identity()` -#' and `scale_continuous_identity()` are generic scales that can work with -#' any aesthetic or set of aesthetics provided via the `aesthetics` +#' already represents aesthetic values that ggplot2 can handle directly. +#' These scales will not produce a legend unless you also supply the `breaks`, +#' `labels`, and type of `guide` you want. +#' +#' The functions `scale_colour_identity()`, `scale_fill_identity()`, `scale_size_identity()`, +#' etc. work on the aesthetics specified in the scale name: `colour`, `fill`, `size`, +#' etc. However, the functions `scale_colour_identity()` and `scale_fill_identity()` also +#' have an optional `aesthetics` argument that can be used to define both `colour` and +#' `fill` aesthetic mappings via a single function call. The functions +#' `scale_discrete_identity()` and `scale_continuous_identity()` are generic scales that +#' can work with any aesthetic or set of aesthetics provided via the `aesthetics` #' argument. #' #' @param ... Other arguments passed on to [discrete_scale()] or diff --git a/R/scale-manual.r b/R/scale-manual.r index cccda4a565..35a4d191c7 100644 --- a/R/scale-manual.r +++ b/R/scale-manual.r @@ -1,9 +1,15 @@ #' Create your own discrete scale #' #' These functions allow you to specify your own set of mappings from levels in the -#' data to aesthetic values. The function `scale_discrete_manual()` is a generic scale -#' that can work with any aesthetic or set of aesthetics provided via the `aesthetics` -#' argument. +#' data to aesthetic values. +#' +#' The functions `scale_colour_manual()`, `scale_fill_manual()`, `scale_size_manual()`, +#' etc. work on the aesthetics specified in the scale name: `colour`, `fill`, `size`, +#' etc. However, the functions `scale_colour_manual()` and `scale_fill_manual()` also +#' have an optional `aesthetics` argument that can be used to define both `colour` and +#' `fill` aesthetic mappings via a single function call (see examples). The function +#' `scale_discrete_manual()` is a generic scale that can work with any aesthetic or set +#' of aesthetics provided via the `aesthetics` argument. #' #' @inheritParams scale_x_discrete #' @inheritDotParams discrete_scale -expand -position -aesthetics @@ -25,6 +31,17 @@ #' cols <- c("8" = "red", "4" = "blue", "6" = "darkgreen", "10" = "orange") #' p + scale_colour_manual(values = cols) #' +#' # You can set color and fill aesthetics at the same time +#' ggplot( +#' mtcars, +#' aes(mpg, wt, colour = factor(cyl), fill = factor(cyl)) +#' ) + +#' geom_point(shape = 21, alpha = 0.5, size = 2) + +#' scale_colour_manual( +#' values = cols, +#' aesthetics = c("colour", "fill") +#' ) +#' #' # As with other scales you can use breaks to control the appearance #' # of the legend. #' p + scale_colour_manual(values = cols) diff --git a/man/scale_identity.Rd b/man/scale_identity.Rd index 7037b9a9be..126ba34d1e 100644 --- a/man/scale_identity.Rd +++ b/man/scale_identity.Rd @@ -41,11 +41,18 @@ same time, via \code{aesthetics = c("colour", "fill")}.} } \description{ Use this set of scales when your data has already been scaled, i.e. it -already represents aesthetic values that ggplot2 can handle directly -This will not produce a legend unless you also supply the \code{breaks}, -\code{labels}, and type of \code{guide} you want. The functions \code{scale_discrete_identity()} -and \code{scale_continuous_identity()} are generic scales that can work with -any aesthetic or set of aesthetics provided via the \code{aesthetics} +already represents aesthetic values that ggplot2 can handle directly. +These scales will not produce a legend unless you also supply the \code{breaks}, +\code{labels}, and type of \code{guide} you want. +} +\details{ +The functions \code{scale_colour_identity()}, \code{scale_fill_identity()}, \code{scale_size_identity()}, +etc. work on the aesthetics specified in the scale name: \code{colour}, \code{fill}, \code{size}, +etc. However, the functions \code{scale_colour_identity()} and \code{scale_fill_identity()} also +have an optional \code{aesthetics} argument that can be used to define both \code{colour} and +\code{fill} aesthetic mappings via a single function call. The functions +\code{scale_discrete_identity()} and \code{scale_continuous_identity()} are generic scales that +can work with any aesthetic or set of aesthetics provided via the \code{aesthetics} argument. } \examples{ diff --git a/man/scale_manual.Rd b/man/scale_manual.Rd index 935af6fe1c..24d178303e 100644 --- a/man/scale_manual.Rd +++ b/man/scale_manual.Rd @@ -83,9 +83,16 @@ same time, via \code{aesthetics = c("colour", "fill")}.} } \description{ These functions allow you to specify your own set of mappings from levels in the -data to aesthetic values. The function \code{scale_discrete_manual()} is a generic scale -that can work with any aesthetic or set of aesthetics provided via the \code{aesthetics} -argument. +data to aesthetic values. +} +\details{ +The functions \code{scale_colour_manual()}, \code{scale_fill_manual()}, \code{scale_size_manual()}, +etc. work on the aesthetics specified in the scale name: \code{colour}, \code{fill}, \code{size}, +etc. However, the functions \code{scale_colour_manual()} and \code{scale_fill_manual()} also +have an optional \code{aesthetics} argument that can be used to define both \code{colour} and +\code{fill} aesthetic mappings via a single function call (see examples). The function +\code{scale_discrete_manual()} is a generic scale that can work with any aesthetic or set +of aesthetics provided via the \code{aesthetics} argument. } \examples{ p <- ggplot(mtcars, aes(mpg, wt)) + @@ -96,6 +103,17 @@ p + scale_colour_manual(values = c("red", "blue", "green")) cols <- c("8" = "red", "4" = "blue", "6" = "darkgreen", "10" = "orange") p + scale_colour_manual(values = cols) +# You can set color and fill aesthetics at the same time +ggplot( + mtcars, + aes(mpg, wt, colour = factor(cyl), fill = factor(cyl)) +) + + geom_point(shape = 21, alpha = 0.5, size = 2) + + scale_colour_manual( + values = cols, + aesthetics = c("colour", "fill") + ) + # As with other scales you can use breaks to control the appearance # of the legend. p + scale_colour_manual(values = cols)