From 6500a307780888d5b49aa32d97ea792c07a733c6 Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 25 Aug 2018 06:35:09 +0900 Subject: [PATCH] Make title, subtitle, caption and tag as labs()'s named arguments (#2669) * add tests for labs() * make label params as the formal arguments of labs() * respect missingness in ggtitle() * improve description about labs() * use waive() to represent missingness in labs() * fix a typo * apply tidyverse style * Enable !!! in labs() * Add a news bullet * Add the Oxford comma --- NEWS.md | 3 +++ R/labels.r | 36 +++++++++++++++++++++++++++--------- man/labs.Rd | 31 ++++++++++++++++++++++++------- tests/testthat/test-labels.r | 23 +++++++++++++++++++++++ 4 files changed, 77 insertions(+), 16 deletions(-) diff --git a/NEWS.md b/NEWS.md index 5790878953..538b27b69b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -50,6 +50,9 @@ coordinates of the geometries. You can customize the calculation method via `fun.geometry` argument (@yutannihilation, #2761). +* `labs()` now has named arguments `title`, `subtitle`, `caption`, and `tag`. + Also, `labs()` now accepts tidyeval (@yutannihilation, #2669). + # ggplot2 3.0.0 ## Breaking changes diff --git a/R/labels.r b/R/labels.r index a25f2e5e72..ec05d5796c 100644 --- a/R/labels.r +++ b/R/labels.r @@ -29,11 +29,21 @@ update_labels <- function(p, labels) { #' the first argument, the `name`). If you're changing other scale options, this #' is recommended. #' -#' @param label The text for the axis, plot title or caption below the plot. -#' @param subtitle the text for the subtitle for the plot which will be -#' displayed below the title. Leave `NULL` for no subtitle. -#' @param ... A list of new name-value pairs. The name should either be -#' an aesthetic, or one of "title", "subtitle", "caption", or "tag". +#' If a plot already has a title, subtitle, caption, etc., and you want to +#' remove it, you can do so by setting the respective argument to `NULL`. For +#' example, if plot `p` has a subtitle, then `p + labs(subtitle = NULL)` will +#' remove the subtitle from the plot. +#' +#' @param label The title of the respective axis (for `xlab()` or `ylab()`) or +#' of the plot (for `ggtitle()`). +#' @param title The text for the title. +#' @param subtitle The text for the subtitle for the plot which will be +#' displayed below the title. +#' @param caption The text for the caption which will be displayed in the +#' bottom-right of the plot by default. +#' @param tag The text for the tag label which will be displayed at the +#' top-left of the plot by default. +#' @param ... A list of new name-value pairs. The name should be an aesthetic. #' @export #' @examples #' p <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) + geom_point() @@ -52,10 +62,18 @@ update_labels <- function(p, labels) { #' # The plot tag appears at the top-left, and is typically used #' # for labelling a subplot with a letter. #' p + labs(title = "title", tag = "A") -labs <- function(...) { - args <- list(...) - if (is.list(args[[1]])) args <- args[[1]] +#' +#' # If you want to remove a label, set it to NULL. +#' p + labs(title = "title") + labs(title = NULL) +labs <- function(..., title = waiver(), subtitle = waiver(), caption = waiver(), tag = waiver()) { + args <- rlang::list2(..., title = title, subtitle = subtitle, caption = caption, tag = tag) + + is_waive <- vapply(args, is.waive, logical(1)) + args <- args[!is_waive] + # remove duplicated arguments + args <- args[!duplicated(names(args))] args <- rename_aes(args) + structure(args, class = "labels") } @@ -73,6 +91,6 @@ ylab <- function(label) { #' @rdname labs #' @export -ggtitle <- function(label, subtitle = NULL) { +ggtitle <- function(label, subtitle = waiver()) { labs(title = label, subtitle = subtitle) } diff --git a/man/labs.Rd b/man/labs.Rd index 830913792e..d258e51e71 100644 --- a/man/labs.Rd +++ b/man/labs.Rd @@ -7,22 +7,31 @@ \alias{ggtitle} \title{Modify axis, legend, and plot labels} \usage{ -labs(...) +labs(..., title = waiver(), subtitle = waiver(), caption = waiver(), + tag = waiver()) xlab(label) ylab(label) -ggtitle(label, subtitle = NULL) +ggtitle(label, subtitle = waiver()) } \arguments{ -\item{...}{A list of new name-value pairs. The name should either be -an aesthetic, or one of "title", "subtitle", "caption", or "tag".} +\item{...}{A list of new name-value pairs. The name should be an aesthetic.} -\item{label}{The text for the axis, plot title or caption below the plot.} +\item{title}{The text for the title.} -\item{subtitle}{the text for the subtitle for the plot which will be -displayed below the title. Leave \code{NULL} for no subtitle.} +\item{subtitle}{The text for the subtitle for the plot which will be +displayed below the title.} + +\item{caption}{The text for the caption which will be displayed in the +bottom-right of the plot by default.} + +\item{tag}{The text for the tag label which will be displayed at the +top-left of the plot by default.} + +\item{label}{The title of the respective axis (for \code{xlab()} or \code{ylab()}) or +of the plot (for \code{ggtitle()}).} } \description{ Good labels are critical for making your plots accessible to a wider @@ -36,6 +45,11 @@ to differentiate between multiple plots. You can also set axis and legend labels in the individual scales (using the first argument, the \code{name}). If you're changing other scale options, this is recommended. + +If a plot already has a title, subtitle, caption, etc., and you want to +remove it, you can do so by setting the respective argument to \code{NULL}. For +example, if plot \code{p} has a subtitle, then \code{p + labs(subtitle = NULL)} will +remove the subtitle from the plot. } \examples{ p <- ggplot(mtcars, aes(mpg, wt, colour = cyl)) + geom_point() @@ -54,4 +68,7 @@ p + labs(caption = "(based on data from ...)") # The plot tag appears at the top-left, and is typically used # for labelling a subplot with a letter. p + labs(title = "title", tag = "A") + +# If you want to remove a label, set it to NULL. +p + labs(title = "title") + labs(title = NULL) } diff --git a/tests/testthat/test-labels.r b/tests/testthat/test-labels.r index 62a8e1b286..a813f36845 100644 --- a/tests/testthat/test-labels.r +++ b/tests/testthat/test-labels.r @@ -25,6 +25,29 @@ test_that("setting guide labels works", { expect_identical(labs(colour = "my label")$colour, "my label") # American spelling expect_identical(labs(color = "my label")$colour, "my label") + + # No extra elements exists + expect_equivalent(labs(title = "my title"), list(title = "my title")) # formal argument + expect_equivalent(labs(colour = "my label"), list(colour = "my label")) # dot + expect_equivalent(labs(foo = "bar"), list(foo = "bar")) # non-existent param + + # labs() has list-splicing semantics + params <- list(title = "my title", tag = "A)") + expect_identical(labs(!!!params)$tag, "A)") + + # NULL is preserved + expect_equivalent(labs(title = NULL), list(title = NULL)) + + # ggtitle works in the same way as labs() + expect_identical(ggtitle("my title")$title, "my title") + expect_identical( + ggtitle("my title", subtitle = "my subtitle")$subtitle, + "my subtitle" + ) + expect_equivalent( + ggtitle("my title", subtitle = NULL), + list(title = "my title", subtitle = NULL) + ) })