From e94c9fe852a83637354e28c0925789d1f345f6d5 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Fri, 25 Jun 2021 13:28:33 +0200 Subject: [PATCH 01/32] Increment version number --- DESCRIPTION | 2 +- NEWS.md | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 9f4bad40c9..3b82c7e7dc 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,5 +1,5 @@ Package: ggplot2 -Version: 3.3.5 +Version: 3.3.5.9000 Title: Create Elegant Data Visualisations Using the Grammar of Graphics Description: A system for 'declaratively' creating graphics, based on "The Grammar of Graphics". You provide the data, tell 'ggplot2' diff --git a/NEWS.md b/NEWS.md index 950c3f555a..67e41b9427 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,5 @@ +# ggplot2 (development version) + # ggplot2 3.3.5 This is a very small release focusing on fixing a couple of untenable issues that surfaced with the 3.3.4 release From 13c07309e5d6798277d5d0c6f76ead88b6112e40 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?St=C3=A9phane=20Guillou?= Date: Wed, 14 Jul 2021 00:06:50 +1000 Subject: [PATCH 02/32] minor typos and formatting fixes in documentation (#4555) --- R/fortify-map.r | 12 ++++++------ man/borders.Rd | 4 ++-- man/map_data.Rd | 8 ++++---- 3 files changed, 12 insertions(+), 12 deletions(-) diff --git a/R/fortify-map.r b/R/fortify-map.r index 81463f79e6..99950d5310 100644 --- a/R/fortify-map.r +++ b/R/fortify-map.r @@ -39,16 +39,16 @@ fortify.map <- function(model, data, ...) { #' Create a data frame of map data #' -#' Easily turn data from the \pkg{maps} package in to a data frame suitable +#' Easily turn data from the \pkg{maps} package into a data frame suitable #' for plotting with ggplot2. #' -#' @param map name of map provided by the \pkg{maps} package. These +#' @param map name of map provided by the \pkg{maps} package. These #' include [maps::county()], [maps::france()], #' [maps::italy()], [maps::nz()], #' [maps::state()], [maps::usa()], #' [maps::world()], [maps::world2()]. -#' @param region name of subregions to include. Defaults to `.` which -#' includes all subregion. See documentation for [maps::map()] +#' @param region name(s) of subregion(s) to include. Defaults to `.` which +#' includes all subregions. See documentation for [maps::map()] #' for more details. #' @param exact should the `region` be treated as a regular expression #' (`FALSE`) or as a fixed string (`TRUE`). @@ -82,8 +82,8 @@ map_data <- function(map, region = ".", exact = FALSE, ...) { #' Create a layer of map borders #' -#' This is a quick and dirty way to get map data (from the maps package) -#' on to your plot. This is a good place to start if you need some crude +#' This is a quick and dirty way to get map data (from the \pkg{maps} package) +#' onto your plot. This is a good place to start if you need some crude #' reference lines, but you'll typically want something more sophisticated #' for communication graphics. #' diff --git a/man/borders.Rd b/man/borders.Rd index 98b2261f17..5dd532e372 100644 --- a/man/borders.Rd +++ b/man/borders.Rd @@ -69,8 +69,8 @@ a warning. If \code{TRUE}, missing values are silently removed.} }} } \description{ -This is a quick and dirty way to get map data (from the maps package) -on to your plot. This is a good place to start if you need some crude +This is a quick and dirty way to get map data (from the \pkg{maps} package) +onto your plot. This is a good place to start if you need some crude reference lines, but you'll typically want something more sophisticated for communication graphics. } diff --git a/man/map_data.Rd b/man/map_data.Rd index 895dcb83c5..943283dd41 100644 --- a/man/map_data.Rd +++ b/man/map_data.Rd @@ -7,14 +7,14 @@ map_data(map, region = ".", exact = FALSE, ...) } \arguments{ -\item{map}{name of map provided by the \pkg{maps} package. These +\item{map}{name of map provided by the \pkg{maps} package. These include \code{\link[maps:county]{maps::county()}}, \code{\link[maps:france]{maps::france()}}, \code{\link[maps:italy]{maps::italy()}}, \code{\link[maps:nz]{maps::nz()}}, \code{\link[maps:state]{maps::state()}}, \code{\link[maps:usa]{maps::usa()}}, \code{\link[maps:world]{maps::world()}}, \code{\link[maps:world2]{maps::world2()}}.} -\item{region}{name of subregions to include. Defaults to \code{.} which -includes all subregion. See documentation for \code{\link[maps:map]{maps::map()}} +\item{region}{name(s) of subregion(s) to include. Defaults to \code{.} which +includes all subregions. See documentation for \code{\link[maps:map]{maps::map()}} for more details.} \item{exact}{should the \code{region} be treated as a regular expression @@ -23,7 +23,7 @@ for more details.} \item{...}{all other arguments passed on to \code{\link[maps:map]{maps::map()}}} } \description{ -Easily turn data from the \pkg{maps} package in to a data frame suitable +Easily turn data from the \pkg{maps} package into a data frame suitable for plotting with ggplot2. } \examples{ From cabb74660e55e16351e1e4d3b671c8c2fd7c644e Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Wed, 4 Aug 2021 23:55:55 +0200 Subject: [PATCH 03/32] Fix small bug in key drawing (#4574) --- R/guide-legend.r | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/guide-legend.r b/R/guide-legend.r index 4fe9eb2b62..7ecb2a0802 100644 --- a/R/guide-legend.r +++ b/R/guide-legend.r @@ -634,7 +634,7 @@ guide_gengrob.legend <- function(guide, theme) { draw_key <- function(i) { bg <- element_render(theme, "legend.key") keys <- lapply(guide$geoms, function(g) { - g$draw_key(g$data[i, ], g$params, key_size) + g$draw_key(g$data[i, , drop = FALSE], g$params, key_size) }) c(list(bg), keys) } From ecee8ce2c1b070be74b29cbcc016d2515b6bffed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Krassowski?= <5832902+krassowski@users.noreply.github.com> Date: Tue, 24 Aug 2021 14:42:34 +0100 Subject: [PATCH 04/32] Fix a typo in changelog (wrong issue number) (#4563) --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 67e41b9427..4a5398a300 100644 --- a/NEWS.md +++ b/NEWS.md @@ -87,7 +87,7 @@ small selection of feature refinements. * It is now deprecated to specify `guides( = FALSE)` or `scale_*(guide = FALSE)` to remove a guide. Please use `guides( = "none")` or `scale_*(guide = "none")` instead - (@yutannihilation, #4094). + (@yutannihilation, #4097) * Fix a bug in `guide_bins()` where keys would disappear if the guide was reversed (@thomasp85, #4210) From 5c22266f6f5ca51e72af52a8133a2619210ca3f9 Mon Sep 17 00:00:00 2001 From: Averi Perny <17169253+averiperny@users.noreply.github.com> Date: Tue, 24 Aug 2021 09:05:01 -0500 Subject: [PATCH 05/32] update cheat sheet link (#4585) Fix #4591 --- README.Rmd | 2 +- README.md | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.Rmd b/README.Rmd index 39180a5b5c..a0664133e0 100644 --- a/README.Rmd +++ b/README.Rmd @@ -38,7 +38,7 @@ devtools::install_github("tidyverse/ggplot2") ## Cheatsheet - + ## Usage diff --git a/README.md b/README.md index da3a046e0c..d41dca7109 100644 --- a/README.md +++ b/README.md @@ -33,7 +33,7 @@ devtools::install_github("tidyverse/ggplot2") ## Cheatsheet - + ## Usage From ffcfaf715cbca377e78a1312bb733e278fa1c888 Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Tue, 7 Sep 2021 23:40:28 +0900 Subject: [PATCH 06/32] Use the dev version of pkgdown (#4543) * Use latest pkgdown * Add a missing topic --- .github/workflows/pkgdown.yaml | 2 +- _pkgdown.yml | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 8da22c8a07..2ff7848d21 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -47,7 +47,7 @@ jobs: - name: Install dependencies run: | pak::local_install_dev_deps(upgrade = TRUE, dependencies = c("all", "Config/Needs/website")) - pak::pkg_install("pkgdown") + pak::pkg_install("r-lib/pkgdown") shell: Rscript {0} - name: Install package diff --git a/_pkgdown.yml b/_pkgdown.yml index 8f046d9152..7290c01f6f 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -118,6 +118,7 @@ reference: - expand_limits - expansion - starts_with("scale_") + - get_alt_text - title: "Guides: axes and legends" desc: > From daed59363d3eb3cded0ebeb122ef0bfd236dd97b Mon Sep 17 00:00:00 2001 From: Balazs Banfai <5557093+banfai@users.noreply.github.com> Date: Sun, 19 Sep 2021 02:05:45 +0200 Subject: [PATCH 07/32] Add tests for values, limits, and breaks in manual scale (#4547) --- tests/testthat/test-scale-manual.r | 54 +++++++++++++++++++++++++++--- 1 file changed, 49 insertions(+), 5 deletions(-) diff --git a/tests/testthat/test-scale-manual.r b/tests/testthat/test-scale-manual.r index b8af871e99..d33fe17da8 100644 --- a/tests/testthat/test-scale-manual.r +++ b/tests/testthat/test-scale-manual.r @@ -1,9 +1,13 @@ context("scale_manual") test_that("names of values used in manual scales", { - s <- scale_colour_manual(values = c("8" = "c","4" = "a","6" = "b")) - s$train(c("4", "6", "8")) - expect_equal(s$map(c("4", "6", "8")), c("a", "b", "c")) + s1 <- scale_colour_manual(values = c("8" = "c", "4" = "a", "6" = "b")) + s1$train(c("4", "6", "8")) + expect_equal(s1$map(c("4", "6", "8")), c("a", "b", "c")) + + s2 <- scale_colour_manual(values = c("8" = "c", "4" = "a", "6" = "b"), na.value = NA) + s2$train(c("4", "8")) + expect_equal(s2$map(c("4", "6", "8")), c("a", NA, "c")) }) @@ -87,13 +91,53 @@ test_that("unnamed values match breaks in manual scales", { }) test_that("limits works (#3262)", { - # named charachter vector + # named character vector s1 <- scale_colour_manual(values = c("8" = "c", "4" = "a", "6" = "b"), limits = c("4", "8"), na.value = NA) s1$train(c("4", "6", "8")) expect_equal(s1$map(c("4", "6", "8")), c("a", NA, "c")) - # named charachter vector + # unnamed character vector s2 <- scale_colour_manual(values = c("c", "a", "b"), limits = c("4", "8"), na.value = NA) s2$train(c("4", "6", "8")) expect_equal(s2$map(c("4", "6", "8")), c("c", NA, "a")) }) + +test_that("fewer values (#3451)", { + # named character vector + s1 <- scale_colour_manual(values = c("4" = "a", "8" = "c"), na.value = NA) + s1$train(c("4", "6", "8")) + expect_equal(s1$map(c("4", "6", "8")), c("a", NA, "c")) + + # unnamed character vector + s2 <- scale_colour_manual(values = c("4", "8"), na.value = NA) + s2$train(c("4", "6", "8")) + expect_error(s2$map(c("4", "6", "8")), "Insufficient values") +}) + +test_that("limits and breaks (#4619)", { + # values don't change legend order + s1 <- scale_colour_manual( + values = c("8" = "c", "4" = "a", "6" = "b"), + ) + s1$train(c("8", "6", "4")) + expect_equal(s1$map(c("8", "6", "4")), c("c", "b", "a")) + expect_equal(s1$break_positions(), c("a", "b", "c")) + + # limits change legend order + s2 <- scale_colour_manual( + values = c("8" = "c", "4" = "a", "6" = "b", "0" = "x"), + limits = c("0", "4", "6", "8") + ) + s2$train(c("8", "6", "4")) + expect_equal(s2$map(c("4", "6", "8")), c("a", "b", "c")) + expect_equal(s2$break_positions(), c("x", "a", "b", "c")) + + # breaks work + s3 <- scale_colour_manual( + values = c("8" = "c", "4" = "a", "6" = "b"), + breaks = c("4", "8") + ) + s3$train(c("4", "6", "8")) + expect_equal(s3$map(c("4", "6", "8")), c("a", "b", "c")) + expect_equal(s3$break_positions(), c("a", "c")) +}) From 759c63c2fd9e00ba3322c1b74b227f63c98d2e06 Mon Sep 17 00:00:00 2001 From: Teun van den Brand <49372158+teunbrand@users.noreply.github.com> Date: Mon, 20 Sep 2021 09:56:11 +0200 Subject: [PATCH 08/32] Manual scale limits default to present names of values (#4619) --- NEWS.md | 6 ++++++ R/scale-manual.r | 5 +++-- tests/testthat/test-scale-manual.r | 2 +- 3 files changed, 10 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 4a5398a300..9364b75a31 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,11 @@ # ggplot2 (development version) +* `scale_*_manual()` no longer displays extra legend keys, or changes their + order, when a named `values` argument has more items than the data. To display + all `values` on the legend instead, use + `scale_*_manual(values = vals, limits = names(vals))`. (@teunbrand, @banfai, + #4511, #4534) + # ggplot2 3.3.5 This is a very small release focusing on fixing a couple of untenable issues that surfaced with the 3.3.4 release diff --git a/R/scale-manual.r b/R/scale-manual.r index 6e408e4c12..28d35dc57b 100644 --- a/R/scale-manual.r +++ b/R/scale-manual.r @@ -132,8 +132,9 @@ manual_scale <- function(aesthetic, values = NULL, breaks = waiver(), ..., limit force(values) } - if (is.null(limits)) { - limits <- names(values) + if (is.null(limits) && !is.null(names(values))) { + # Limits as function to access `values` names later on (#4619) + limits <- function(x) intersect(x, names(values)) } # order values according to breaks diff --git a/tests/testthat/test-scale-manual.r b/tests/testthat/test-scale-manual.r index d33fe17da8..9355558893 100644 --- a/tests/testthat/test-scale-manual.r +++ b/tests/testthat/test-scale-manual.r @@ -117,7 +117,7 @@ test_that("fewer values (#3451)", { test_that("limits and breaks (#4619)", { # values don't change legend order s1 <- scale_colour_manual( - values = c("8" = "c", "4" = "a", "6" = "b"), + values = c("8" = "c", "4" = "a", "6" = "b") ) s1$train(c("8", "6", "4")) expect_equal(s1$map(c("8", "6", "4")), c("c", "b", "a")) From f5e01baec86469762a707e2ca8354378d0d31ab1 Mon Sep 17 00:00:00 2001 From: Alonso Melgar Lopez Date: Fri, 29 Oct 2021 07:22:17 -0500 Subject: [PATCH 09/32] added scale_y_continuous labels accepts plotmath expressions (#4640) --- R/scale-.r | 1 + man/binned_scale.Rd | 1 + man/continuous_scale.Rd | 1 + man/discrete_scale.Rd | 1 + man/ggplot2-package.Rd | 5 +---- man/scale_binned.Rd | 1 + man/scale_continuous.Rd | 1 + man/scale_date.Rd | 1 + man/scale_discrete.Rd | 1 + man/scale_gradient.Rd | 1 + man/scale_grey.Rd | 1 + man/scale_hue.Rd | 1 + man/scale_linetype.Rd | 1 + man/scale_manual.Rd | 1 + man/scale_shape.Rd | 1 + man/scale_size.Rd | 1 + man/scale_steps.Rd | 1 + 17 files changed, 17 insertions(+), 4 deletions(-) diff --git a/R/scale-.r b/R/scale-.r index 3fa2f6cbde..6c289e63b7 100644 --- a/R/scale-.r +++ b/R/scale-.r @@ -36,6 +36,7 @@ #' - `waiver()` for the default labels computed by the #' transformation object #' - A character vector giving labels (must be same length as `breaks`) +#' - An expression vector (must be the same length as breaks). See ?plotmath for details. #' - A function that takes the breaks as input and returns labels #' as output. Also accepts rlang [lambda][rlang::as_function()] function #' notation. diff --git a/man/binned_scale.Rd b/man/binned_scale.Rd index 951ac64858..05ec50c87b 100644 --- a/man/binned_scale.Rd +++ b/man/binned_scale.Rd @@ -58,6 +58,7 @@ Also accepts rlang \link[rlang:as_function]{lambda} function notation. \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/continuous_scale.Rd b/man/continuous_scale.Rd index 5f55695097..1dbf902268 100644 --- a/man/continuous_scale.Rd +++ b/man/continuous_scale.Rd @@ -71,6 +71,7 @@ number of breaks given by the transformation.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/discrete_scale.Rd b/man/discrete_scale.Rd index 456361bb61..59cd8a9771 100644 --- a/man/discrete_scale.Rd +++ b/man/discrete_scale.Rd @@ -52,6 +52,7 @@ notation. \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/ggplot2-package.Rd b/man/ggplot2-package.Rd index becc53d969..2503e4a66a 100644 --- a/man/ggplot2-package.Rd +++ b/man/ggplot2-package.Rd @@ -8,10 +8,7 @@ \description{ \if{html}{\figure{logo.png}{options: align='right' alt='logo' width='120'}} -A system for 'declaratively' creating graphics, - based on "The Grammar of Graphics". You provide the data, tell 'ggplot2' - how to map variables to aesthetics, what graphical primitives to use, - and it takes care of the details. +A system for 'declaratively' creating graphics, based on "The Grammar of Graphics". You provide the data, tell 'ggplot2' how to map variables to aesthetics, what graphical primitives to use, and it takes care of the details. } \seealso{ Useful links: diff --git a/man/scale_binned.Rd b/man/scale_binned.Rd index f2a34bfbb1..0963d298cf 100644 --- a/man/scale_binned.Rd +++ b/man/scale_binned.Rd @@ -71,6 +71,7 @@ Also accepts rlang \link[rlang:as_function]{lambda} function notation. \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_continuous.Rd b/man/scale_continuous.Rd index 926885a2b8..7eed5df1a4 100644 --- a/man/scale_continuous.Rd +++ b/man/scale_continuous.Rd @@ -93,6 +93,7 @@ number of breaks given by the transformation.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_date.Rd b/man/scale_date.Rd index f4ccbb0f49..528def2616 100644 --- a/man/scale_date.Rd +++ b/man/scale_date.Rd @@ -127,6 +127,7 @@ specified, \code{date_breaks} wins.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_discrete.Rd b/man/scale_discrete.Rd index b7c901a2d6..1d18498f6c 100644 --- a/man/scale_discrete.Rd +++ b/man/scale_discrete.Rd @@ -56,6 +56,7 @@ omitted.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_gradient.Rd b/man/scale_gradient.Rd index 1dfbe880e7..2a399e9eb3 100644 --- a/man/scale_gradient.Rd +++ b/man/scale_gradient.Rd @@ -126,6 +126,7 @@ number of breaks given by the transformation.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_grey.Rd b/man/scale_grey.Rd index 4c73eaacef..d2a3458711 100644 --- a/man/scale_grey.Rd +++ b/man/scale_grey.Rd @@ -65,6 +65,7 @@ omitted.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_hue.Rd b/man/scale_hue.Rd index fe497c05aa..a989031964 100644 --- a/man/scale_hue.Rd +++ b/man/scale_hue.Rd @@ -71,6 +71,7 @@ omitted.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_linetype.Rd b/man/scale_linetype.Rd index 05c0d84193..b8ef69db2d 100644 --- a/man/scale_linetype.Rd +++ b/man/scale_linetype.Rd @@ -59,6 +59,7 @@ omitted.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_manual.Rd b/man/scale_manual.Rd index b4386bbc58..ffc783d872 100644 --- a/man/scale_manual.Rd +++ b/man/scale_manual.Rd @@ -71,6 +71,7 @@ omitted.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_shape.Rd b/man/scale_shape.Rd index ccf0906ac2..0cef550ad0 100644 --- a/man/scale_shape.Rd +++ b/man/scale_shape.Rd @@ -59,6 +59,7 @@ omitted.} \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_size.Rd b/man/scale_size.Rd index 649267b2e8..83ce8692e8 100644 --- a/man/scale_size.Rd +++ b/man/scale_size.Rd @@ -72,6 +72,7 @@ Also accepts rlang \link[rlang:as_function]{lambda} function notation. \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. diff --git a/man/scale_steps.Rd b/man/scale_steps.Rd index 16b2ad1fd3..73a9ec2a1e 100644 --- a/man/scale_steps.Rd +++ b/man/scale_steps.Rd @@ -112,6 +112,7 @@ Also accepts rlang \link[rlang:as_function]{lambda} function notation. \item \code{waiver()} for the default labels computed by the transformation object \item A character vector giving labels (must be same length as \code{breaks}) +\item An expression vector (must be the same length as breaks). See ?plotmath for details. \item A function that takes the breaks as input and returns labels as output. Also accepts rlang \link[rlang:as_function]{lambda} function notation. From 08749f8b08a700c4598ad9c52735b312da2c79b9 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 1 Nov 2021 19:16:27 +0100 Subject: [PATCH 10/32] Update to newest CI (#4656) --- .github/workflows/R-CMD-check.yaml | 19 +++---- .github/workflows/pkgdown.yaml | 52 +++++-------------- .github/workflows/pr-commands.yaml | 36 ++++++++++--- .github/workflows/test-coverage.yaml | 46 ++++------------ R/geom-segment.r | 2 + R/geom-sf.R | 12 +++-- README.Rmd | 6 ++- README.md | 12 +++-- codecov.yml | 2 + man/geom_segment.Rd | 2 + man/ggsf.Rd | 12 +++-- tests/testthat/test-annotate.r | 1 + tests/testthat/test-coord-map.R | 10 ++-- tests/testthat/test-geom-hline-vline-abline.R | 1 + 14 files changed, 100 insertions(+), 113 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 50a86ee67e..0a9593bd02 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -1,10 +1,14 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help +# +# NOTE: This workflow is overkill for most R packages and +# check-standard.yaml is likely a better choice. +# usethis::use_github_action("check-standard") will install it. on: push: - branches: - - master + branches: [main, master] pull_request: - branches: - - master + branches: [main, master] name: R-CMD-check @@ -29,8 +33,8 @@ jobs: - {os: ubuntu-18.04, r: '4.0', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - {os: ubuntu-18.04, r: '3.6', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - {os: ubuntu-18.04, r: '3.5', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '3.4', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '3.3', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} + - {os: ubuntu-18.04, r: '3.4', vdiffr: false, xref: false, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} + - {os: ubuntu-18.04, r: '3.3', vdiffr: false, xref: false, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} env: R_REMOTES_NO_ERRORS_FROM_WARNINGS: true @@ -74,16 +78,13 @@ jobs: do eval sudo $cmd done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "18.04"))') - - name: Install system dependencies on macOS if: runner.os == 'macOS' run: | # XQuartz is needed by vdiffr brew install xquartz - # Use only binary packages echo 'options(pkgType = "binary")' >> ~/.Rprofile - - name: Install dependencies run: | remotes::install_deps(dependencies = TRUE) diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 2ff7848d21..6d10b7c806 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -1,60 +1,34 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: - - master - release: types: [published] + branches: [main, master] + tags: ['*'] name: pkgdown jobs: pkgdown: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest env: - RSPM: https://packagemanager.rstudio.com/cran/__linux__/bionic/latest GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} - steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-r@v1 - id: install-r - - uses: r-lib/actions/setup-pandoc@v1 - - name: Install pak and query dependencies - run: | - install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/") - saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds") - shell: Rscript {0} - - - name: Restore R package cache - uses: actions/cache@v2 + - uses: r-lib/actions/setup-r@v1 with: - path: | - ${{ env.R_LIBS_USER }}/* - !${{ env.R_LIBS_USER }}/pak - key: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-1-${{ hashFiles('.github/r-depends.rds') }} - restore-keys: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-1- + use-public-rspm: true - - name: Install system dependencies - if: runner.os == 'Linux' - run: | - pak::local_system_requirements(execute = TRUE) - pak::pkg_system_requirements("pkgdown", execute = TRUE) - shell: Rscript {0} - - - name: Install dependencies - run: | - pak::local_install_dev_deps(upgrade = TRUE, dependencies = c("all", "Config/Needs/website")) - pak::pkg_install("r-lib/pkgdown") - shell: Rscript {0} - - - name: Install package - run: R CMD INSTALL . + - uses: r-lib/actions/setup-r-dependencies@v1 + with: + extra-packages: pkgdown + needs: website - name: Deploy package run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" + git config --local user.name "$GITHUB_ACTOR" + git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml index e5edf9f778..1cdafbf7e4 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -1,55 +1,75 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: issue_comment: types: [created] + name: Commands + jobs: document: if: startsWith(github.event.comment.body, '/document') name: document - runs-on: macOS-latest + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 + - uses: r-lib/actions/pr-fetch@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: r-lib/actions/setup-r@v1 - - name: Install dependencies - run: Rscript -e 'install.packages(c("remotes", "roxygen2"))' -e 'remotes::install_deps(dependencies = TRUE)' + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v1 + with: + extra-packages: roxygen2 + - name: Document run: Rscript -e 'roxygen2::roxygenise()' + - name: commit run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" + git config --local user.name "$GITHUB_ACTOR" + git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" git add man/\* NAMESPACE git commit -m 'Document' + - uses: r-lib/actions/pr-push@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} + style: if: startsWith(github.event.comment.body, '/style') name: style - runs-on: macOS-latest + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 + - uses: r-lib/actions/pr-fetch@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} + - uses: r-lib/actions/setup-r@v1 + - name: Install dependencies run: Rscript -e 'install.packages("styler")' + - name: Style run: Rscript -e 'styler::style_pkg()' + - name: commit run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" + git config --local user.name "$GITHUB_ACTOR" + git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" git add \*.R git commit -m 'Style' + - uses: r-lib/actions/pr-push@v1 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index e3c16455cb..3c0da1c97c 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -1,57 +1,29 @@ +# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - branches: - - master + branches: [main, master] pull_request: - branches: - - master + branches: [main, master] name: test-coverage -# Increment this version when we want to clear cache -env: - cache-version: v1 - jobs: test-coverage: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest env: - RSPM: https://packagemanager.rstudio.com/cran/__linux__/bionic/latest GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 - uses: r-lib/actions/setup-r@v1 - id: install-r - - - name: Install pak and query dependencies - run: | - install.packages("pak", repos = "https://r-lib.github.io/p/pak/dev/") - saveRDS(pak::pkg_deps("local::.", dependencies = TRUE), ".github/r-depends.rds") - shell: Rscript {0} - - - name: Restore R package cache - uses: actions/cache@v2 with: - path: | - ${{ env.R_LIBS_USER }}/* - !${{ env.R_LIBS_USER }}/pak - key: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-${{ env.cache-version }}-${{ hashFiles('.github/r-depends.rds') }} - restore-keys: ubuntu-18.04-${{ steps.install-r.outputs.installed-r-version }}-${{ env.cache-version }}- + use-public-rspm: true - - name: Install system dependencies - if: runner.os == 'Linux' - run: | - pak::local_system_requirements(execute = TRUE) - pak::pkg_system_requirements("covr", execute = TRUE) - shell: Rscript {0} - - - name: Install dependencies - run: | - pak::local_install_dev_deps(upgrade = TRUE) - pak::pkg_install("covr") - shell: Rscript {0} + - uses: r-lib/actions/setup-r-dependencies@v1 + with: + extra-packages: covr - name: Test coverage run: covr::codecov() diff --git a/R/geom-segment.r b/R/geom-segment.r index d21ec10ead..01965739bd 100644 --- a/R/geom-segment.r +++ b/R/geom-segment.r @@ -38,10 +38,12 @@ #' arrow = arrow(length = unit(0.03, "npc")) #' ) #' +#' if (requireNamespace('maps', quietly = TRUE)) { #' ggplot(seals, aes(long, lat)) + #' geom_segment(aes(xend = long + delta_long, yend = lat + delta_lat), #' arrow = arrow(length = unit(0.1,"cm"))) + #' borders("state") +#' } #' #' # Use lineend and linejoin to change the style of the segments #' df2 <- expand.grid( diff --git a/R/geom-sf.R b/R/geom-sf.R index 1a41974f94..4367ade3be 100644 --- a/R/geom-sf.R +++ b/R/geom-sf.R @@ -88,8 +88,15 @@ #' annotate("point", x = -80, y = 35, colour = "red", size = 4) + #' coord_sf(default_crs = sf::st_crs(4326)) #' +#' # To add labels, use geom_sf_label(). +#' ggplot(nc_3857[1:3, ]) + +#' geom_sf(aes(fill = AREA)) + +#' geom_sf_label(aes(label = NAME)) +#' } +#' #' # Thanks to the power of sf, a geom_sf nicely handles varying projections #' # setting the aspect ratio correctly. +#' if (requireNamespace('maps', quietly = TRUE)) { #' library(maps) #' world1 <- sf::st_as_sf(map('world', plot = FALSE, fill = TRUE)) #' ggplot() + geom_sf(data = world1) @@ -99,11 +106,6 @@ #' "+proj=laea +y_0=0 +lon_0=155 +lat_0=-90 +ellps=WGS84 +no_defs" #' ) #' ggplot() + geom_sf(data = world2) -#' -#' # To add labels, use geom_sf_label(). -#' ggplot(nc_3857[1:3, ]) + -#' geom_sf(aes(fill = AREA)) + -#' geom_sf_label(aes(label = NAME)) #' } #' @name ggsf NULL diff --git a/README.Rmd b/README.Rmd index a0664133e0..f0722fbd8e 100644 --- a/README.Rmd +++ b/README.Rmd @@ -14,9 +14,11 @@ knitr::opts_chunk$set( # ggplot2 -[![R build status](https://github.com/tidyverse/ggplot2/workflows/R-CMD-check/badge.svg)](https://github.com/tidyverse/ggplot2/actions) -[![Coverage Status](https://img.shields.io/codecov/c/github/tidyverse/ggplot2/master.svg)](https://codecov.io/github/tidyverse/ggplot2?branch=master) + +[![R-CMD-check](https://github.com/tidyverse/ggplot2/workflows/R-CMD-check/badge.svg)](https://github.com/tidyverse/ggplot2/actions) +[![Codecov test coverage](https://codecov.io/gh/tidyverse/ggplot2/branch/main/graph/badge.svg)](https://app.codecov.io/gh/tidyverse/ggplot2?branch=main) [![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/ggplot2)](https://cran.r-project.org/package=ggplot2) + ## Overview diff --git a/README.md b/README.md index d41dca7109..85254af37a 100644 --- a/README.md +++ b/README.md @@ -3,11 +3,13 @@ # ggplot2 -[![R build -status](https://github.com/tidyverse/ggplot2/workflows/R-CMD-check/badge.svg)](https://github.com/tidyverse/ggplot2/actions) -[![Coverage -Status](https://img.shields.io/codecov/c/github/tidyverse/ggplot2/master.svg)](https://codecov.io/github/tidyverse/ggplot2?branch=master) -[![CRAN\_Status\_Badge](https://www.r-pkg.org/badges/version/ggplot2)](https://cran.r-project.org/package=ggplot2) + + +[![R-CMD-check](https://github.com/tidyverse/ggplot2/workflows/R-CMD-check/badge.svg)](https://github.com/tidyverse/ggplot2/actions) +[![Codecov test +coverage](https://codecov.io/gh/tidyverse/ggplot2/branch/main/graph/badge.svg)](https://app.codecov.io/gh/tidyverse/ggplot2?branch=main) +[![CRAN_Status_Badge](https://www.r-pkg.org/badges/version/ggplot2)](https://cran.r-project.org/package=ggplot2) + ## Overview diff --git a/codecov.yml b/codecov.yml index 8f36b6cc1b..04c5585990 100644 --- a/codecov.yml +++ b/codecov.yml @@ -6,7 +6,9 @@ coverage: default: target: auto threshold: 1% + informational: true patch: default: target: auto threshold: 1% + informational: true diff --git a/man/geom_segment.Rd b/man/geom_segment.Rd index 799adac1c3..5cfa8057b5 100644 --- a/man/geom_segment.Rd +++ b/man/geom_segment.Rd @@ -149,10 +149,12 @@ b + geom_curve( arrow = arrow(length = unit(0.03, "npc")) ) +if (requireNamespace('maps', quietly = TRUE)) { ggplot(seals, aes(long, lat)) + geom_segment(aes(xend = long + delta_long, yend = lat + delta_lat), arrow = arrow(length = unit(0.1,"cm"))) + borders("state") +} # Use lineend and linejoin to change the style of the segments df2 <- expand.grid( diff --git a/man/ggsf.Rd b/man/ggsf.Rd index de3910dfde..2e62839852 100644 --- a/man/ggsf.Rd +++ b/man/ggsf.Rd @@ -341,8 +341,15 @@ ggplot(nc_3857) + annotate("point", x = -80, y = 35, colour = "red", size = 4) + coord_sf(default_crs = sf::st_crs(4326)) +# To add labels, use geom_sf_label(). +ggplot(nc_3857[1:3, ]) + + geom_sf(aes(fill = AREA)) + + geom_sf_label(aes(label = NAME)) +} + # Thanks to the power of sf, a geom_sf nicely handles varying projections # setting the aspect ratio correctly. +if (requireNamespace('maps', quietly = TRUE)) { library(maps) world1 <- sf::st_as_sf(map('world', plot = FALSE, fill = TRUE)) ggplot() + geom_sf(data = world1) @@ -352,11 +359,6 @@ world2 <- sf::st_transform( "+proj=laea +y_0=0 +lon_0=155 +lat_0=-90 +ellps=WGS84 +no_defs" ) ggplot() + geom_sf(data = world2) - -# To add labels, use geom_sf_label(). -ggplot(nc_3857[1:3, ]) + - geom_sf(aes(fill = AREA)) + - geom_sf_label(aes(label = NAME)) } } \seealso{ diff --git a/tests/testthat/test-annotate.r b/tests/testthat/test-annotate.r index b510c3ced2..f44aee148a 100644 --- a/tests/testthat/test-annotate.r +++ b/tests/testthat/test-annotate.r @@ -31,6 +31,7 @@ test_that("segment annotations transform with scales", { }) test_that("annotation_* has dummy data assigned and don't inherit aes", { + skip_if(packageVersion("base") < "3.5.0") custom <- annotation_custom(zeroGrob()) logtick <- annotation_logticks() library(maps) diff --git a/tests/testthat/test-coord-map.R b/tests/testthat/test-coord-map.R index ba46588a79..9473820cdf 100644 --- a/tests/testthat/test-coord-map.R +++ b/tests/testthat/test-coord-map.R @@ -1,9 +1,9 @@ context("coord_map") -us_map <- map_data("usa") -p_us <- ggplot(us_map, aes(x = long, y = lat, group = group)) - test_that("USA state map drawn", { + skip_if(packageVersion("base") < "3.5.0") + us_map <- map_data("usa") + p_us <- ggplot(us_map, aes(x = long, y = lat, group = group)) expect_doppelganger( "USA mercator", p_us + @@ -13,6 +13,9 @@ test_that("USA state map drawn", { }) test_that("coord_map scale position can be switched", { + skip_if(packageVersion("base") < "3.5.0") + us_map <- map_data("usa") + p_us <- ggplot(us_map, aes(x = long, y = lat, group = group)) expect_doppelganger( "coord_map switched scale position", p_us + @@ -24,6 +27,7 @@ test_that("coord_map scale position can be switched", { }) test_that("Inf is squished to range", { + skip_if(packageVersion("base") < "3.5.0") d <- cdata( ggplot(data_frame(x = 0, y = 0)) + geom_point(aes(x,y)) + diff --git a/tests/testthat/test-geom-hline-vline-abline.R b/tests/testthat/test-geom-hline-vline-abline.R index 746bfff144..e57563ed1b 100644 --- a/tests/testthat/test-geom-hline-vline-abline.R +++ b/tests/testthat/test-geom-hline-vline-abline.R @@ -29,6 +29,7 @@ test_that("check h/v/abline transformed on basic projections", { }) test_that("curved lines in map projections", { + skip_if(packageVersion("base") < "3.5.0") nz <- subset(map_data("nz"), region == "North.Island ") nzmap <- ggplot(nz, aes(long, lat, group = group)) + geom_path() + From c856b7f2b69ac7cba421a6f82099d14785d57d5b Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Wed, 3 Nov 2021 08:32:27 +0900 Subject: [PATCH 11/32] set.seed() before sample() (#4502) --- R/position-jitterdodge.R | 1 + R/scale-brewer.r | 1 + R/scale-hue.r | 1 + R/scale-shape.r | 1 + R/scale-viridis.r | 1 + man/position_jitterdodge.Rd | 1 + man/scale_brewer.Rd | 1 + man/scale_hue.Rd | 1 + man/scale_shape.Rd | 1 + man/scale_viridis.Rd | 1 + 10 files changed, 10 insertions(+) diff --git a/R/position-jitterdodge.R b/R/position-jitterdodge.R index abb5dd8ace..ff57bd3e8c 100644 --- a/R/position-jitterdodge.R +++ b/R/position-jitterdodge.R @@ -13,6 +13,7 @@ #' @inheritParams position_jitter #' @export #' @examples +#' set.seed(596) #' dsub <- diamonds[sample(nrow(diamonds), 1000), ] #' ggplot(dsub, aes(x = cut, y = carat, fill = clarity)) + #' geom_boxplot(outlier.size = 0) + diff --git a/R/scale-brewer.r b/R/scale-brewer.r index 6fc450e171..9b87429365 100644 --- a/R/scale-brewer.r +++ b/R/scale-brewer.r @@ -40,6 +40,7 @@ #' @rdname scale_brewer #' @export #' @examples +#' set.seed(596) #' dsamp <- diamonds[sample(nrow(diamonds), 1000), ] #' (d <- ggplot(dsamp, aes(carat, price)) + #' geom_point(aes(colour = clarity))) diff --git a/R/scale-hue.r b/R/scale-hue.r index 29b3ef4315..e2dc6cd229 100644 --- a/R/scale-hue.r +++ b/R/scale-hue.r @@ -15,6 +15,7 @@ #' @family colour scales #' @examples #' \donttest{ +#' set.seed(596) #' dsamp <- diamonds[sample(nrow(diamonds), 1000), ] #' (d <- ggplot(dsamp, aes(carat, price)) + geom_point(aes(colour = clarity))) #' diff --git a/R/scale-shape.r b/R/scale-shape.r index f5d148b7a2..ed66bfcd05 100644 --- a/R/scale-shape.r +++ b/R/scale-shape.r @@ -14,6 +14,7 @@ #' @rdname scale_shape #' @export #' @examples +#' set.seed(596) #' dsmall <- diamonds[sample(nrow(diamonds), 100), ] #' #' (d <- ggplot(dsmall, aes(carat, price)) + geom_point(aes(shape = cut))) diff --git a/R/scale-viridis.r b/R/scale-viridis.r index d90ca0cce9..1ab871bdfb 100644 --- a/R/scale-viridis.r +++ b/R/scale-viridis.r @@ -20,6 +20,7 @@ #' @export #' @examples #' # viridis is the default colour/fill scale for ordered factors +#' set.seed(596) #' dsamp <- diamonds[sample(nrow(diamonds), 1000), ] #' ggplot(dsamp, aes(carat, price)) + #' geom_point(aes(colour = clarity)) diff --git a/man/position_jitterdodge.Rd b/man/position_jitterdodge.Rd index 49d0ad55d0..d158162211 100644 --- a/man/position_jitterdodge.Rd +++ b/man/position_jitterdodge.Rd @@ -35,6 +35,7 @@ This is primarily used for aligning points generated through a fill aesthetic supplied). } \examples{ +set.seed(596) dsub <- diamonds[sample(nrow(diamonds), 1000), ] ggplot(dsub, aes(x = cut, y = carat, fill = clarity)) + geom_boxplot(outlier.size = 0) + diff --git a/man/scale_brewer.Rd b/man/scale_brewer.Rd index e3e4994e5f..07f0e514ff 100644 --- a/man/scale_brewer.Rd +++ b/man/scale_brewer.Rd @@ -134,6 +134,7 @@ Modify the palette through the \code{palette} argument. } \examples{ +set.seed(596) dsamp <- diamonds[sample(nrow(diamonds), 1000), ] (d <- ggplot(dsamp, aes(carat, price)) + geom_point(aes(colour = clarity))) diff --git a/man/scale_hue.Rd b/man/scale_hue.Rd index a989031964..3f29ab5500 100644 --- a/man/scale_hue.Rd +++ b/man/scale_hue.Rd @@ -114,6 +114,7 @@ It does not generate colour-blind safe palettes. } \examples{ \donttest{ +set.seed(596) dsamp <- diamonds[sample(nrow(diamonds), 1000), ] (d <- ggplot(dsamp, aes(carat, price)) + geom_point(aes(colour = clarity))) diff --git a/man/scale_shape.Rd b/man/scale_shape.Rd index 0cef550ad0..9156950f0a 100644 --- a/man/scale_shape.Rd +++ b/man/scale_shape.Rd @@ -81,6 +81,7 @@ a continuous variable to shape unless \code{scale_shape_binned()} is used. Still as shape has no inherent order, this use is not advised. } \examples{ +set.seed(596) dsmall <- diamonds[sample(nrow(diamonds), 100), ] (d <- ggplot(dsmall, aes(carat, price)) + geom_point(aes(shape = cut))) diff --git a/man/scale_viridis.Rd b/man/scale_viridis.Rd index 7246c07384..12c8ed4192 100644 --- a/man/scale_viridis.Rd +++ b/man/scale_viridis.Rd @@ -136,6 +136,7 @@ with common forms of colour blindness. See also } \examples{ # viridis is the default colour/fill scale for ordered factors +set.seed(596) dsamp <- diamonds[sample(nrow(diamonds), 1000), ] ggplot(dsamp, aes(carat, price)) + geom_point(aes(colour = clarity)) From 6e3ac8116195126d3cc843e50fca64bf6e4f43a4 Mon Sep 17 00:00:00 2001 From: r2evans Date: Wed, 3 Nov 2021 03:16:40 -0400 Subject: [PATCH 12/32] Correct doc for print.ggplot, returns 'x' not 'data' (#4390) (#4657) --- NEWS.md | 3 +++ R/plot.r | 4 +--- man/print.ggplot.Rd | 4 +--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9364b75a31..939d829a49 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Updated documentation for `print.ggplot` to reflect that it returns + the original plot, not the result of `ggplot_build()`. (@r2evans, #4390) + * `scale_*_manual()` no longer displays extra legend keys, or changes their order, when a named `values` argument has more items than the data. To display all `values` on the legend instead, use diff --git a/R/plot.r b/R/plot.r index d1b9a5f5a7..51f10a3187 100644 --- a/R/plot.r +++ b/R/plot.r @@ -137,9 +137,7 @@ is.ggplot <- function(x) inherits(x, "ggplot") #' @param vp viewport to draw plot in #' @param ... other arguments not used by this method #' @keywords hplot -#' @return Invisibly returns the result of [ggplot_build()], which -#' is a list with components that contain the plot itself, the data, -#' information about the scales, panels etc. +#' @return Invisibly returns the original plot. #' @export #' @method print ggplot #' @examples diff --git a/man/print.ggplot.Rd b/man/print.ggplot.Rd index 68d2df86a9..72a84220b9 100644 --- a/man/print.ggplot.Rd +++ b/man/print.ggplot.Rd @@ -19,9 +19,7 @@ \item{...}{other arguments not used by this method} } \value{ -Invisibly returns the result of \code{\link[=ggplot_build]{ggplot_build()}}, which -is a list with components that contain the plot itself, the data, -information about the scales, panels etc. +Invisibly returns the original plot. } \description{ Generally, you do not need to print or plot a ggplot2 plot explicitly: the From 4c1c8df622fc8903db8960fea9d1eb22dc3935ec Mon Sep 17 00:00:00 2001 From: Elio Campitelli Date: Tue, 9 Nov 2021 05:16:57 -0300 Subject: [PATCH 13/32] Allows `breaks` to be a function in `geom_contour()` (#4652) --- NEWS.md | 2 ++ R/geom-contour.r | 11 ++++++++--- R/stat-contour.r | 15 +++++++++++---- man/geom_contour.Rd | 13 ++++++++++--- man/geom_density_2d.Rd | 13 ++++++++++--- tests/testthat/test-stat-contour.R | 4 +++- 6 files changed, 44 insertions(+), 14 deletions(-) diff --git a/NEWS.md b/NEWS.md index 939d829a49..fe7fef0b0d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ all `values` on the legend instead, use `scale_*_manual(values = vals, limits = names(vals))`. (@teunbrand, @banfai, #4511, #4534) + +* `geom_contour()` now accepts a function in the `breaks` argument (@eliocamp, #4652). # ggplot2 3.3.5 This is a very small release focusing on fixing a couple of untenable issues diff --git a/R/geom-contour.r b/R/geom-contour.r index cc25a70da4..4cdb0cd234 100644 --- a/R/geom-contour.r +++ b/R/geom-contour.r @@ -19,9 +19,14 @@ #' @inheritParams geom_path #' @param bins Number of contour bins. Overridden by `binwidth`. #' @param binwidth The width of the contour bins. Overridden by `breaks`. -#' @param breaks Numeric vector to set the contour breaks. Overrides `binwidth` -#' and `bins`. By default, this is a vector of length ten with [pretty()] -#' breaks. +#' @param breaks One of: +#' - Numeric vector to set the contour breaks +#' - A function that takes the range of the data and binwidth as input +#' and returns breaks as output. A function can be created from a formula +#' (e.g. ~ fullseq(.x, .y)). +#' +#' Overrides `binwidth` and `bins`. By default, this is a vector of length +#' ten with [pretty()] breaks. #' @seealso [geom_density_2d()]: 2d density contours #' @export #' @examples diff --git a/R/stat-contour.r b/R/stat-contour.r index c96d69c673..695af32be9 100644 --- a/R/stat-contour.r +++ b/R/stat-contour.r @@ -144,10 +144,17 @@ StatContourFilled <- ggproto("StatContourFilled", Stat, #' @noRd #' contour_breaks <- function(z_range, bins = NULL, binwidth = NULL, breaks = NULL) { - if (!is.null(breaks)) { + breaks <- allow_lambda(breaks) + + if (is.numeric(breaks)) { return(breaks) } + breaks_fun <- fullseq + if (is.function(breaks)) { + breaks_fun <- breaks + } + # If no parameters set, use pretty bins if (is.null(bins) && is.null(binwidth)) { breaks <- pretty(z_range, 10) @@ -167,20 +174,20 @@ contour_breaks <- function(z_range, bins = NULL, binwidth = NULL, breaks = NULL) } binwidth <- diff(z_range) / (bins - 1) - breaks <- fullseq(z_range, binwidth) + breaks <- breaks_fun(z_range, binwidth) # Sometimes the above sequence yields one bin too few. # If this happens, try again. if (length(breaks) < bins + 1) { binwidth <- diff(z_range) / bins - breaks <- fullseq(z_range, binwidth) + breaks <- breaks_fun(z_range, binwidth) } return(breaks) } # if we haven't returned yet, compute breaks from binwidth - fullseq(z_range, binwidth) + breaks_fun(z_range, binwidth) } #' Compute isoband objects diff --git a/man/geom_contour.Rd b/man/geom_contour.Rd index 1277d9b84b..ae5b40a987 100644 --- a/man/geom_contour.Rd +++ b/man/geom_contour.Rd @@ -102,9 +102,16 @@ to the paired geom/stat.} \item{binwidth}{The width of the contour bins. Overridden by \code{breaks}.} -\item{breaks}{Numeric vector to set the contour breaks. Overrides \code{binwidth} -and \code{bins}. By default, this is a vector of length ten with \code{\link[=pretty]{pretty()}} -breaks.} +\item{breaks}{One of: +\itemize{ +\item Numeric vector to set the contour breaks +\item A function that takes the range of the data and binwidth as input +and returns breaks as output. A function can be created from a formula +(e.g. ~ fullseq(.x, .y)). +} + +Overrides \code{binwidth} and \code{bins}. By default, this is a vector of length +ten with \code{\link[=pretty]{pretty()}} breaks.} \item{lineend}{Line end style (round, butt, square).} diff --git a/man/geom_density_2d.Rd b/man/geom_density_2d.Rd index c0daf09211..d2961df949 100644 --- a/man/geom_density_2d.Rd +++ b/man/geom_density_2d.Rd @@ -99,9 +99,16 @@ a call to a position adjustment function.} \describe{ \item{\code{bins}}{Number of contour bins. Overridden by \code{binwidth}.} \item{\code{binwidth}}{The width of the contour bins. Overridden by \code{breaks}.} - \item{\code{breaks}}{Numeric vector to set the contour breaks. Overrides \code{binwidth} -and \code{bins}. By default, this is a vector of length ten with \code{\link[=pretty]{pretty()}} -breaks.} + \item{\code{breaks}}{One of: +\itemize{ +\item Numeric vector to set the contour breaks +\item A function that takes the range of the data and binwidth as input +and returns breaks as output. A function can be created from a formula +(e.g. ~ fullseq(.x, .y)). +} + +Overrides \code{binwidth} and \code{bins}. By default, this is a vector of length +ten with \code{\link[=pretty]{pretty()}} breaks.} }} \item{contour_var}{Character string identifying the variable to contour diff --git a/tests/testthat/test-stat-contour.R b/tests/testthat/test-stat-contour.R index 61df774756..a48a368931 100644 --- a/tests/testthat/test-stat-contour.R +++ b/tests/testthat/test-stat-contour.R @@ -32,7 +32,7 @@ test_that("contouring irregularly spaced data works", { expect_setequal(d8$y, c(2, 20/9, 16/9)) }) -test_that("contour breaks can be set manually and by bins and binwidth", { +test_that("contour breaks can be set manually and by bins and binwidth and a function", { range <- c(0, 1) expect_equal(contour_breaks(range), pretty(range, 10)) expect_identical(contour_breaks(range, breaks = 1:3), 1:3) @@ -40,6 +40,8 @@ test_that("contour breaks can be set manually and by bins and binwidth", { # shifting the range by 0.2 hits another execution branch in contour_breaks() expect_length(contour_breaks(range + 0.2, bins = 5), 6) expect_equal(resolution(contour_breaks(range, binwidth = 0.3)), 0.3) + expect_equal(contour_breaks(range), contour_breaks(range, breaks = fullseq)) + expect_equal(contour_breaks(range), contour_breaks(range, breaks = ~fullseq(.x, .y))) }) test_that("geom_contour_filled() and stat_contour_filled() result in identical layer data", { From ad3dbfc904b69c37a5165264d49a880688f84cae Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Tue, 9 Nov 2021 17:18:31 +0900 Subject: [PATCH 14/32] Use testthat 3e (#4522) --- DESCRIPTION | 3 +- tests/testthat/test-add.R | 2 -- tests/testthat/test-aes-calculated.r | 2 -- tests/testthat/test-aes-grouping.r | 2 -- tests/testthat/test-aes-setting.r | 2 -- tests/testthat/test-aes.r | 6 ++-- tests/testthat/test-annotate.r | 2 -- tests/testthat/test-build.r | 8 ++--- tests/testthat/test-coord-.r | 2 -- tests/testthat/test-coord-cartesian.R | 2 -- tests/testthat/test-coord-flip.R | 2 -- tests/testthat/test-coord-map.R | 2 -- tests/testthat/test-coord-polar.r | 2 -- tests/testthat/test-coord-train.r | 2 -- tests/testthat/test-coord-transform.R | 10 +++--- tests/testthat/test-coord_sf.R | 2 -- tests/testthat/test-data.r | 36 +++++++++---------- tests/testthat/test-draw-key.R | 2 -- tests/testthat/test-empty-data.r | 2 -- tests/testthat/test-error.R | 2 -- tests/testthat/test-facet-.r | 20 +++++------ tests/testthat/test-facet-labels.r | 2 -- tests/testthat/test-facet-layout.r | 2 -- tests/testthat/test-facet-map.r | 2 -- tests/testthat/test-facet-strips.r | 2 -- tests/testthat/test-fortify.r | 14 +++++--- tests/testthat/test-function-args.r | 2 -- tests/testthat/test-geom-bar.R | 2 -- tests/testthat/test-geom-boxplot.R | 2 -- tests/testthat/test-geom-col.R | 2 -- tests/testthat/test-geom-dotplot.R | 2 -- tests/testthat/test-geom-freqpoly.R | 2 -- tests/testthat/test-geom-hex.R | 2 -- tests/testthat/test-geom-hline-vline-abline.R | 2 -- tests/testthat/test-geom-path.R | 2 -- tests/testthat/test-geom-point.R | 2 -- tests/testthat/test-geom-polygon.R | 2 -- tests/testthat/test-geom-quantile.R | 19 +++++----- tests/testthat/test-geom-raster.R | 2 -- tests/testthat/test-geom-ribbon.R | 2 -- tests/testthat/test-geom-rug.R | 2 -- tests/testthat/test-geom-rule.R | 1 - tests/testthat/test-geom-sf.R | 2 -- tests/testthat/test-geom-smooth.R | 2 -- tests/testthat/test-geom-text.R | 2 -- tests/testthat/test-geom-tile.R | 2 -- tests/testthat/test-geom-violin.R | 2 -- tests/testthat/test-ggproto.R | 2 -- tests/testthat/test-ggsave.R | 2 -- tests/testthat/test-grid-utils.R | 2 -- tests/testthat/test-guides.R | 11 +++--- tests/testthat/test-labellers.R | 2 -- tests/testthat/test-labels.r | 17 +++++---- tests/testthat/test-layer.r | 4 +-- tests/testthat/test-munch.r | 2 -- tests/testthat/test-performance.R | 2 -- tests/testthat/test-plot-summary-api.R | 6 ++-- tests/testthat/test-position-dodge2.R | 2 -- tests/testthat/test-position-nudge.R | 2 -- tests/testthat/test-position-stack.R | 2 -- tests/testthat/test-position_dodge.R | 2 -- tests/testthat/test-prohibited-functions.R | 2 -- tests/testthat/test-qplot.r | 12 +++---- tests/testthat/test-range.r | 2 -- tests/testthat/test-rbind-dfs.R | 2 -- tests/testthat/test-sanitise-dim.r | 26 +++++++++----- tests/testthat/test-scale-brewer.R | 2 -- tests/testthat/test-scale-colour-continuous.R | 2 -- tests/testthat/test-scale-date.R | 2 -- tests/testthat/test-scale-discrete.R | 2 -- tests/testthat/test-scale-gradient.R | 4 +-- tests/testthat/test-scale-manual.r | 2 -- tests/testthat/test-scale-type.R | 2 -- tests/testthat/test-scale_date.R | 2 -- tests/testthat/test-scales-breaks-labels.r | 4 +-- tests/testthat/test-scales.r | 6 ++-- tests/testthat/test-sec-axis.R | 2 -- tests/testthat/test-stat-bin.R | 2 -- tests/testthat/test-stat-bin2d.R | 2 -- tests/testthat/test-stat-boxplot.R | 2 -- tests/testthat/test-stat-contour.R | 15 +++++--- tests/testthat/test-stat-density.R | 2 -- tests/testthat/test-stat-density2d.R | 2 -- tests/testthat/test-stat-ecdf.R | 2 -- tests/testthat/test-stat-ellipsis.R | 2 -- tests/testthat/test-stat-function.R | 2 -- tests/testthat/test-stat-hex.R | 2 -- tests/testthat/test-stat-sf-coordinates.R | 2 -- tests/testthat/test-stat-sum.R | 2 -- tests/testthat/test-stat-summary.R | 2 -- tests/testthat/test-stats.r | 9 +++-- tests/testthat/test-theme.r | 2 -- tests/testthat/test-utilities.r | 2 -- tests/testthat/test-viridis.R | 2 -- tests/testthat/test-zzz.R | 2 -- 95 files changed, 123 insertions(+), 258 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 3b82c7e7dc..89af5c1bd2 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -64,7 +64,7 @@ Suggests: rpart, sf (>= 0.7-3), svglite (>= 1.2.0.9001), - testthat (>= 2.1.0), + testthat (>= 3.0.0), vdiffr (>= 1.0.0), xml2 Enhances: sp @@ -274,3 +274,4 @@ Config/Needs/website: tidyr, forcats, tidyverse/tidytemplate +Config/testthat/edition: 3 diff --git a/tests/testthat/test-add.R b/tests/testthat/test-add.R index f2dab24957..a860a55845 100644 --- a/tests/testthat/test-add.R +++ b/tests/testthat/test-add.R @@ -1,5 +1,3 @@ -context("Adding plot elements") - test_that("mapping class is preserved when adding uneval objects", { p <- ggplot(mtcars) + aes(wt, mpg) expect_identical(class(p$mapping), "uneval") diff --git a/tests/testthat/test-aes-calculated.r b/tests/testthat/test-aes-calculated.r index f42584d194..8377eea5fa 100644 --- a/tests/testthat/test-aes-calculated.r +++ b/tests/testthat/test-aes-calculated.r @@ -1,5 +1,3 @@ -context("test-aes-calculated.r") - test_that("constants aren't calculated", { expect_equal(is_calculated_aes(aes(1, "a", TRUE)), c(FALSE, FALSE, FALSE)) }) diff --git a/tests/testthat/test-aes-grouping.r b/tests/testthat/test-aes-grouping.r index f4af9b4127..2744dfd2fc 100644 --- a/tests/testthat/test-aes-grouping.r +++ b/tests/testthat/test-aes-grouping.r @@ -1,5 +1,3 @@ -context("Aesthetics (grouping)") - df <- data_frame( x = 1:4, a = c("a", "a", "b", "b"), diff --git a/tests/testthat/test-aes-setting.r b/tests/testthat/test-aes-setting.r index 5dba19dfb4..baa6a12077 100644 --- a/tests/testthat/test-aes-setting.r +++ b/tests/testthat/test-aes-setting.r @@ -1,5 +1,3 @@ -context("Aes - setting values") - test_that("aesthetic parameters match length of data", { df <- data_frame(x = 1:5, y = 1:5) p <- ggplot(df, aes(x, y)) diff --git a/tests/testthat/test-aes.r b/tests/testthat/test-aes.r index 043ed8f641..391d1a09d3 100644 --- a/tests/testthat/test-aes.r +++ b/tests/testthat/test-aes.r @@ -1,5 +1,3 @@ -context("Creating aesthetic mappings") - test_that("aes() captures input expressions", { out <- aes(mpg, wt + 1) expect_identical(out$x, quo(mpg)) @@ -36,7 +34,9 @@ test_that("aes_q() & aes_string() preserve explicit NULLs", { test_that("aes_all() converts strings into mappings", { expect_equal( aes_all(c("x", "y", "col", "pch")), - aes(x, y, colour = col, shape = pch) + aes(x, y, colour = col, shape = pch), + # ignore the environments of quosures + ignore_attr = TRUE ) }) diff --git a/tests/testthat/test-annotate.r b/tests/testthat/test-annotate.r index f44aee148a..6a5f36c128 100644 --- a/tests/testthat/test-annotate.r +++ b/tests/testthat/test-annotate.r @@ -1,5 +1,3 @@ -context("annotate") - test_that("dates in segment annotation work", { dt <- structure(list(month = structure(c(1364774400, 1377993600), class = c("POSIXct", "POSIXt"), tzone = "UTC"), total = c(-10.3, diff --git a/tests/testthat/test-build.r b/tests/testthat/test-build.r index db89887b40..24930a0373 100644 --- a/tests/testthat/test-build.r +++ b/tests/testthat/test-build.r @@ -1,6 +1,4 @@ # Test the complete path from plot specification to rendered data -context("Plot building") - df <- data_frame(x = 1:3, y = 3:1, z = letters[1:3]) test_that("there is one data frame for each layer", { @@ -19,8 +17,8 @@ test_that("position aesthetics are coerced to correct type", { l1 <- ggplot(df, aes(x, y)) + geom_point() d1 <- layer_data(l1, 1) - expect_is(d1$x, "numeric") - expect_is(d1$y, "numeric") + expect_type(d1$x, "double") + expect_type(d1$y, "double") l2 <- ggplot(df, aes(x, z)) + geom_point() + scale_x_discrete() d2 <- layer_data(l2, 1) @@ -52,5 +50,5 @@ test_that("strings are not converted to factors", { p <- ggplot(df, aes(x, y)) + geom_text(aes(label = label), parse = TRUE) - expect_is(layer_data(p)$label, "character") + expect_type(layer_data(p)$label, "character") }) diff --git a/tests/testthat/test-coord-.r b/tests/testthat/test-coord-.r index 4ee2f8f7dc..2d1c083a4e 100644 --- a/tests/testthat/test-coord-.r +++ b/tests/testthat/test-coord-.r @@ -1,5 +1,3 @@ -context("test-coord-.r") - test_that("clipping is on by default", { p <- ggplot() coord <- ggplot_build(p)$layout$coord diff --git a/tests/testthat/test-coord-cartesian.R b/tests/testthat/test-coord-cartesian.R index c81dbff143..5b0ea913d3 100644 --- a/tests/testthat/test-coord-cartesian.R +++ b/tests/testthat/test-coord-cartesian.R @@ -1,5 +1,3 @@ -context("coord_cartesian") - test_that("clipping can be turned off and on", { # clip on by default p <- ggplot() + coord_cartesian() diff --git a/tests/testthat/test-coord-flip.R b/tests/testthat/test-coord-flip.R index 0182c5d6bc..c3a24300b6 100644 --- a/tests/testthat/test-coord-flip.R +++ b/tests/testthat/test-coord-flip.R @@ -1,5 +1,3 @@ -context("test-coord-flip.r") - test_that("secondary labels are correctly turned off", { # Using a visual test because the labels are only generated during rendering expect_doppelganger("turning off secondary title with coord_flip", diff --git a/tests/testthat/test-coord-map.R b/tests/testthat/test-coord-map.R index 9473820cdf..89497aba46 100644 --- a/tests/testthat/test-coord-map.R +++ b/tests/testthat/test-coord-map.R @@ -1,5 +1,3 @@ -context("coord_map") - test_that("USA state map drawn", { skip_if(packageVersion("base") < "3.5.0") us_map <- map_data("usa") diff --git a/tests/testthat/test-coord-polar.r b/tests/testthat/test-coord-polar.r index 8baac118f1..c3b25ce2fa 100644 --- a/tests/testthat/test-coord-polar.r +++ b/tests/testthat/test-coord-polar.r @@ -1,5 +1,3 @@ -context("coord_polar") - test_that("polar distance is calculated correctly", { dat <- data_frame( theta = c(0, 2*pi, 2, 6, 6, 1, 1, 0), diff --git a/tests/testthat/test-coord-train.r b/tests/testthat/test-coord-train.r index afca806e6c..2b712499e3 100644 --- a/tests/testthat/test-coord-train.r +++ b/tests/testthat/test-coord-train.r @@ -1,5 +1,3 @@ -context("coord_train") - test_that("NA's don't appear in breaks", { # Returns true if any major/minor breaks have an NA diff --git a/tests/testthat/test-coord-transform.R b/tests/testthat/test-coord-transform.R index 1b2ecfcc11..1e2f882f87 100644 --- a/tests/testthat/test-coord-transform.R +++ b/tests/testthat/test-coord-transform.R @@ -1,5 +1,3 @@ -context("coord_trans") - test_that("warnings are generated when cord_trans() results in new infinite values", { p <- ggplot(head(diamonds, 20)) + geom_bar(aes(x = cut)) + @@ -9,8 +7,12 @@ test_that("warnings are generated when cord_trans() results in new infinite valu geom_point() + coord_trans(x = "log") - expect_warning(ggplot_gtable(ggplot_build(p)), "Transformation introduced infinite values in y-axis") - expect_warning(ggplot_gtable(ggplot_build(p2)), "Transformation introduced infinite values in x-axis") + # TODO: These multiple warnings should be summarized nicely. Until this gets + # fixed, this test ignores all the following errors than the first one. + suppressWarnings({ + expect_warning(ggplot_gtable(ggplot_build(p)), "Transformation introduced infinite values in y-axis") + expect_warning(ggplot_gtable(ggplot_build(p2)), "Transformation introduced infinite values in x-axis") + }) }) test_that("no warnings are generated when original data has Inf values, but no new Inf values created from the transformation", { diff --git a/tests/testthat/test-coord_sf.R b/tests/testthat/test-coord_sf.R index fe65f72da4..3986774cea 100644 --- a/tests/testthat/test-coord_sf.R +++ b/tests/testthat/test-coord_sf.R @@ -1,5 +1,3 @@ -context("coord_sf") - test_that("basic plot builds without error", { skip_if_not_installed("sf") diff --git a/tests/testthat/test-data.r b/tests/testthat/test-data.r index a363479670..57acb22544 100644 --- a/tests/testthat/test-data.r +++ b/tests/testthat/test-data.r @@ -1,25 +1,25 @@ -context("Data") - test_that("stringsAsFactors doesn't affect results", { - old <- getOption("stringsAsFactors") - on.exit(options(stringsAsFactors = old), add = TRUE) + skip_if(as.integer(R.Version()$major) >= 4L, "stringsAsFactors only affects R <4.0") + + old <- getOption("stringsAsFactors") + on.exit(options(stringsAsFactors = old), add = TRUE) - dat.character <- data_frame(x = letters[5:1], y = 1:5) - dat.factor <- data_frame(x = letters[5:1], y = 1:5) + dat.character <- data_frame(x = letters[5:1], y = 1:5) + dat.factor <- data_frame(x = letters[5:1], y = 1:5) - base <- ggplot(mapping = aes(x, y)) + geom_point() - xlabels <- function(x) x$layout$panel_params[[1]]$x$get_labels() + base <- ggplot(mapping = aes(x, y)) + geom_point() + xlabels <- function(x) x$layout$panel_params[[1]]$x$get_labels() - options(stringsAsFactors = TRUE) - char_true <- ggplot_build(base %+% dat.character) - factor_true <- ggplot_build(base %+% dat.factor) + options(stringsAsFactors = TRUE) + char_true <- ggplot_build(base %+% dat.character) + factor_true <- ggplot_build(base %+% dat.factor) - options(stringsAsFactors = FALSE) - char_false <- ggplot_build(base %+% dat.character) - factor_false <- ggplot_build(base %+% dat.factor) + options(stringsAsFactors = FALSE) + char_false <- ggplot_build(base %+% dat.character) + factor_false <- ggplot_build(base %+% dat.factor) - expect_equal(xlabels(char_true), letters[1:5]) - expect_equal(xlabels(char_false), letters[1:5]) - expect_equal(xlabels(factor_true), letters[1:5]) - expect_equal(xlabels(factor_false), letters[1:5]) + expect_equal(xlabels(char_true), letters[1:5]) + expect_equal(xlabels(char_false), letters[1:5]) + expect_equal(xlabels(factor_true), letters[1:5]) + expect_equal(xlabels(factor_false), letters[1:5]) }) diff --git a/tests/testthat/test-draw-key.R b/tests/testthat/test-draw-key.R index 956e3755bc..d378473b20 100644 --- a/tests/testthat/test-draw-key.R +++ b/tests/testthat/test-draw-key.R @@ -1,6 +1,4 @@ # Setting of legend key glyphs has to be tested visually -context("Legend key glyphs") - test_that("alternative key glyphs work", { df <- data_frame(x = 1:3, y = 3:1, z = letters[1:3]) diff --git a/tests/testthat/test-empty-data.r b/tests/testthat/test-empty-data.r index 26c0cb8bcc..b9c72ced1b 100644 --- a/tests/testthat/test-empty-data.r +++ b/tests/testthat/test-empty-data.r @@ -1,5 +1,3 @@ -context('Empty data') - df0 <- data_frame(mpg = numeric(0), wt = numeric(0), am = numeric(0), cyl = numeric(0)) test_that("layers with empty data are silently omitted", { diff --git a/tests/testthat/test-error.R b/tests/testthat/test-error.R index bcf5f56c44..d845ef12e7 100644 --- a/tests/testthat/test-error.R +++ b/tests/testthat/test-error.R @@ -1,5 +1,3 @@ -context("error") - test_that("various misuses of +.gg (#2638)", { expect_error( { diff --git a/tests/testthat/test-facet-.r b/tests/testthat/test-facet-.r index e54eeb7797..44a08bf1ca 100644 --- a/tests/testthat/test-facet-.r +++ b/tests/testthat/test-facet-.r @@ -1,5 +1,3 @@ -context("Facetting") - test_that("as_facets_list() coerces formulas", { expect_identical(as_facets_list(~foo), list(quos(), quos(foo = foo))) expect_identical(as_facets_list(~foo + bar), list(quos(), quos(foo = foo, bar = bar))) @@ -277,15 +275,16 @@ test_that("combine_vars() generates the correct combinations", { factor = factor(c("level1", "level2")), stringsAsFactors = FALSE ) + attr(df_all, "out.attrs") <- NULL vars_all <- vars(letter = letter, number = number, boolean = boolean, factor = factor) - expect_equivalent( + expect_equal( combine_vars(list(df_one), vars = vars_all), df_one ) - expect_equivalent( + expect_equal( combine_vars(list(df_all), vars = vars_all), df_all ) @@ -295,21 +294,22 @@ test_that("combine_vars() generates the correct combinations", { # NAs are kept with with drop = TRUE # drop keeps all combinations of data, regardless of the combinations in which # they appear in the data (in addition to keeping unused factor levels) - expect_equivalent( + expect_equal( combine_vars(list(df_one), vars = vars_all, drop = FALSE), - df_all[order(df_all$letter, df_all$number, df_all$boolean, df_all$factor), ] + df_all[order(df_all$letter, df_all$number, df_all$boolean, df_all$factor), ], + ignore_attr = TRUE # do not compare `row.names` ) }) test_that("drop = FALSE in combine_vars() keeps unused factor levels", { df <- data_frame(x = factor("a", levels = c("a", "b"))) - expect_equivalent( + expect_equal( combine_vars(list(df), vars = vars(x = x), drop = TRUE), - data_frame(x = factor("a")) + data_frame(x = factor("a", levels = c("a", "b"))) ) - expect_equivalent( + expect_equal( combine_vars(list(df), vars = vars(x = x), drop = FALSE), - data_frame(x = factor(c("a", "b"))) + data_frame(x = factor(c("a", "b"), levels = c("a", "b"))) ) }) diff --git a/tests/testthat/test-facet-labels.r b/tests/testthat/test-facet-labels.r index ba87713197..6d086e0b7b 100644 --- a/tests/testthat/test-facet-labels.r +++ b/tests/testthat/test-facet-labels.r @@ -1,5 +1,3 @@ -context("Facet Labels") - get_labels_matrix <- function(plot, ...) { data <- ggplot_build(plot) layout <- data$layout diff --git a/tests/testthat/test-facet-layout.r b/tests/testthat/test-facet-layout.r index c3cc9d139f..b975135557 100644 --- a/tests/testthat/test-facet-layout.r +++ b/tests/testthat/test-facet-layout.r @@ -1,5 +1,3 @@ -context("Facetting (layout)") - a <- data_frame(a = c(1, 1, 2, 2), b = c(1, 2, 1, 1)) b <- data_frame(a = 3) c <- data_frame(b = 3) diff --git a/tests/testthat/test-facet-map.r b/tests/testthat/test-facet-map.r index 1a0c1ba9e6..a1b10fb48b 100644 --- a/tests/testthat/test-facet-map.r +++ b/tests/testthat/test-facet-map.r @@ -1,5 +1,3 @@ -context("Facetting (mapping)") - df <- expand.grid(a = 1:2, b = 1:2) df_a <- unique(df["a"]) df_b <- unique(df["b"]) diff --git a/tests/testthat/test-facet-strips.r b/tests/testthat/test-facet-strips.r index a9747f9f30..4536eb73d7 100644 --- a/tests/testthat/test-facet-strips.r +++ b/tests/testthat/test-facet-strips.r @@ -1,5 +1,3 @@ -context("Facet Strips") - strip_layout <- function(p) { data <- ggplot_build(p) plot <- data$plot diff --git a/tests/testthat/test-fortify.r b/tests/testthat/test-fortify.r index d6510493f8..fcc0951d7d 100644 --- a/tests/testthat/test-fortify.r +++ b/tests/testthat/test-fortify.r @@ -1,5 +1,3 @@ -context("Fortify") - test_that("spatial polygons have correct ordering", { skip_if_not_installed("sp") @@ -31,9 +29,17 @@ test_that("spatial polygons have correct ordering", { polys2 <- rev(polys) polys2_sp <- sp::SpatialPolygons(polys2) fake_sp2 <- sp::SpatialPolygonsDataFrame(polys2_sp, fake_data) - fake_sp2_fortified <- fortify(fake_sp2) + expected <- fortify(fake_sp2) + expected <- expected[order(expected$id, expected$order), ] + + actual <- fortify(fake_sp) + + # the levels are different, so these columns need to be converted to character to compare + expected$group <- as.character(expected$group) + actual$group <- as.character(actual$group) - expect_equivalent(fortify(fake_sp), fake_sp2_fortified[order(fake_sp2_fortified$id, fake_sp2_fortified$order), ]) + # Use expect_equal(ignore_attr = TRUE) to ignore rownames + expect_equal(actual, expected, ignore_attr = TRUE) }) test_that("fortify.default proves a helpful error with class uneval", { diff --git a/tests/testthat/test-function-args.r b/tests/testthat/test-function-args.r index 080fb5b71c..5e9eb77072 100644 --- a/tests/testthat/test-function-args.r +++ b/tests/testthat/test-function-args.r @@ -1,5 +1,3 @@ -context("function-args") - filter_args <- function(x) { all_names <- names(x) all_names <- setdiff(all_names, c("self", "data", "scales", "coordinates", "...")) diff --git a/tests/testthat/test-geom-bar.R b/tests/testthat/test-geom-bar.R index fa3f6bd7a3..b36a9c401e 100644 --- a/tests/testthat/test-geom-bar.R +++ b/tests/testthat/test-geom-bar.R @@ -1,5 +1,3 @@ -context("geom_bar") - test_that("geom_bar removes bars with parts outside the plot limits", { dat <- data_frame(x = c("a", "b", "b", "c", "c", "c")) diff --git a/tests/testthat/test-geom-boxplot.R b/tests/testthat/test-geom-boxplot.R index d6993488bc..dd8c077877 100644 --- a/tests/testthat/test-geom-boxplot.R +++ b/tests/testthat/test-geom-boxplot.R @@ -1,5 +1,3 @@ -context("geom_boxplot") - # thanks wch for providing the test code test_that("geom_boxplot range includes all outliers", { dat <- data_frame(x = 1, y = c(-(1:20) ^ 3, (1:20) ^ 3) ) diff --git a/tests/testthat/test-geom-col.R b/tests/testthat/test-geom-col.R index 7d8b0548f1..d4e158ccce 100644 --- a/tests/testthat/test-geom-col.R +++ b/tests/testthat/test-geom-col.R @@ -1,5 +1,3 @@ -context("geom_col") - test_that("geom_col removes columns with parts outside the plot limits", { dat <- data_frame(x = c(1, 2, 3)) diff --git a/tests/testthat/test-geom-dotplot.R b/tests/testthat/test-geom-dotplot.R index e2829fec99..8049961508 100644 --- a/tests/testthat/test-geom-dotplot.R +++ b/tests/testthat/test-geom-dotplot.R @@ -1,5 +1,3 @@ -context("geom_dotplot") - skip_on_cran() # This test suite is long-running (on cran) and is skipped set.seed(111) diff --git a/tests/testthat/test-geom-freqpoly.R b/tests/testthat/test-geom-freqpoly.R index 74df4d09ff..52de05f4a7 100644 --- a/tests/testthat/test-geom-freqpoly.R +++ b/tests/testthat/test-geom-freqpoly.R @@ -1,5 +1,3 @@ -context("geom_freqpoly") - test_that("can do frequency polygon with categorical x", { df <- data_frame(x = rep(letters[1:3], 3:1)) diff --git a/tests/testthat/test-geom-hex.R b/tests/testthat/test-geom-hex.R index d815955792..3cffeb8a66 100644 --- a/tests/testthat/test-geom-hex.R +++ b/tests/testthat/test-geom-hex.R @@ -1,5 +1,3 @@ -context("geom_hex") - test_that("density and value summaries are available", { df <- data_frame(x = c(1, 1, 1, 2), y = c(1, 1, 1, 2)) base <- ggplot(df, aes(x, y)) + diff --git a/tests/testthat/test-geom-hline-vline-abline.R b/tests/testthat/test-geom-hline-vline-abline.R index e57563ed1b..91b3108983 100644 --- a/tests/testthat/test-geom-hline-vline-abline.R +++ b/tests/testthat/test-geom-hline-vline-abline.R @@ -1,5 +1,3 @@ -context("geom-hline-vline-abline") - # Visual tests ------------------------------------------------------------ diff --git a/tests/testthat/test-geom-path.R b/tests/testthat/test-geom-path.R index 40e7b210e9..217733d9dd 100644 --- a/tests/testthat/test-geom-path.R +++ b/tests/testthat/test-geom-path.R @@ -1,5 +1,3 @@ -context("geom-path") - test_that("keep_mid_true drops leading/trailing FALSE", { expect_equal(keep_mid_true(c(F, F)), c(F, F)) expect_equal(keep_mid_true(c(F, T, F, T, F)), c(F, T, T, T, F)) diff --git a/tests/testthat/test-geom-point.R b/tests/testthat/test-geom-point.R index b60f2b8821..bfa3300447 100644 --- a/tests/testthat/test-geom-point.R +++ b/tests/testthat/test-geom-point.R @@ -1,5 +1,3 @@ -context("geom-point") - test_that("single strings translate to their corresponding integers", { expect_equal(translate_shape_string("square open"), 0) }) diff --git a/tests/testthat/test-geom-polygon.R b/tests/testthat/test-geom-polygon.R index 964a8af45a..334e62043f 100644 --- a/tests/testthat/test-geom-polygon.R +++ b/tests/testthat/test-geom-polygon.R @@ -1,5 +1,3 @@ -context("geom-polygon") - # Visual tests ------------------------------------------------------------ diff --git a/tests/testthat/test-geom-quantile.R b/tests/testthat/test-geom-quantile.R index 61906b43a3..bdcef0ac7f 100644 --- a/tests/testthat/test-geom-quantile.R +++ b/tests/testthat/test-geom-quantile.R @@ -1,5 +1,3 @@ -context("geom-quantile") - test_that("geom_quantile matches quantile regression", { skip_if_not_installed("quantreg") @@ -35,25 +33,28 @@ test_that("geom_quantile matches quantile regression", { pred_rq_test_25 <- pred_rq[, c("x", "Q_25")] colnames(pred_rq_test_25) <- c("x", "y") - # Use expect_equivalent() to ignore rownames - expect_equivalent( + # Use expect_equal(ignore_attr = TRUE) to ignore rownames + expect_equal( ggplot_data[ggplot_data$quantile == 0.25, c("x", "y")], - pred_rq_test_25 + pred_rq_test_25, + ignore_attr = TRUE ) pred_rq_test_50 <- pred_rq[, c("x", "Q_50")] colnames(pred_rq_test_50) <- c("x", "y") - expect_equivalent( + expect_equal( ggplot_data[ggplot_data$quantile == 0.5, c("x", "y")], - pred_rq_test_50 + pred_rq_test_50, + ignore_attr = TRUE ) pred_rq_test_75 <- pred_rq[, c("x", "Q_75")] colnames(pred_rq_test_75) <- c("x", "y") - expect_equivalent( + expect_equal( ggplot_data[ggplot_data$quantile == 0.75, c("x", "y")], - pred_rq_test_75 + pred_rq_test_75, + ignore_attr = TRUE ) }) diff --git a/tests/testthat/test-geom-raster.R b/tests/testthat/test-geom-raster.R index 890ef96692..cbdb9731d9 100644 --- a/tests/testthat/test-geom-raster.R +++ b/tests/testthat/test-geom-raster.R @@ -1,5 +1,3 @@ -context("geom-raster") - # Visual tests ------------------------------------------------------------ diff --git a/tests/testthat/test-geom-ribbon.R b/tests/testthat/test-geom-ribbon.R index 535e313651..9da04bef5a 100644 --- a/tests/testthat/test-geom-ribbon.R +++ b/tests/testthat/test-geom-ribbon.R @@ -1,5 +1,3 @@ -context("geom_ribbon") - test_that("NAs are not dropped from the data", { df <- data_frame(x = 1:5, y = c(1, 1, NA, 1, 1)) diff --git a/tests/testthat/test-geom-rug.R b/tests/testthat/test-geom-rug.R index 15c8d498b5..25204ef7ed 100644 --- a/tests/testthat/test-geom-rug.R +++ b/tests/testthat/test-geom-rug.R @@ -1,5 +1,3 @@ -context("geom_rug") - n = 10 df <- data_frame(x = 1:n, y = (1:n)^3) p <- ggplot(df, aes(x, y)) + geom_point() + geom_rug(sides = 'l') diff --git a/tests/testthat/test-geom-rule.R b/tests/testthat/test-geom-rule.R index 542957232d..e41ab41103 100644 --- a/tests/testthat/test-geom-rule.R +++ b/tests/testthat/test-geom-rule.R @@ -1,4 +1,3 @@ -context("geom_rule") # tests for geom_vline, geom_hline & geom_abline df <- data_frame(x = 1:3, y = 3:1) diff --git a/tests/testthat/test-geom-sf.R b/tests/testthat/test-geom-sf.R index f09e85ed3e..d3c5acc91f 100644 --- a/tests/testthat/test-geom-sf.R +++ b/tests/testthat/test-geom-sf.R @@ -1,5 +1,3 @@ -context("geom-sf") - test_that("geom_sf() determines the legend type automatically", { skip_if_not_installed("sf") if (packageVersion("sf") < "0.5.3") skip("Need sf 0.5.3") diff --git a/tests/testthat/test-geom-smooth.R b/tests/testthat/test-geom-smooth.R index 12c4718014..a317d78e07 100644 --- a/tests/testthat/test-geom-smooth.R +++ b/tests/testthat/test-geom-smooth.R @@ -1,5 +1,3 @@ -context("geom_smooth") - test_that("data is ordered by x", { df <- data_frame(x = c(1, 5, 2, 3, 4), y = 1:5) diff --git a/tests/testthat/test-geom-text.R b/tests/testthat/test-geom-text.R index d870a3a645..4f6573e076 100644 --- a/tests/testthat/test-geom-text.R +++ b/tests/testthat/test-geom-text.R @@ -1,5 +1,3 @@ -context("geom_text") - # compute_just ------------------------------------------------------------ test_that("vertical and horizontal positions are equivalent", { diff --git a/tests/testthat/test-geom-tile.R b/tests/testthat/test-geom-tile.R index be5dd39518..00261386ca 100644 --- a/tests/testthat/test-geom-tile.R +++ b/tests/testthat/test-geom-tile.R @@ -1,5 +1,3 @@ -context("geom_tile") - test_that("accepts width and height params", { df <- data_frame(x = c("a", "b"), y = c("a", "b")) diff --git a/tests/testthat/test-geom-violin.R b/tests/testthat/test-geom-violin.R index 751596d3b2..d9d81b135b 100644 --- a/tests/testthat/test-geom-violin.R +++ b/tests/testthat/test-geom-violin.R @@ -1,5 +1,3 @@ -context("geom_violin") - test_that("range is expanded", { df <- rbind( data_frame(x = "a", y = c(0, runif(10), 1)), diff --git a/tests/testthat/test-ggproto.R b/tests/testthat/test-ggproto.R index d6ac15b0c8..c0d4401e9e 100644 --- a/tests/testthat/test-ggproto.R +++ b/tests/testthat/test-ggproto.R @@ -1,5 +1,3 @@ -context("ggproto") - test_that(".DollarNames retrieves inherited methods", { A <- ggproto("A", NULL, a = 1) B <- ggproto("B", A, b = 2) diff --git a/tests/testthat/test-ggsave.R b/tests/testthat/test-ggsave.R index 10069b4004..0d7e022d7f 100644 --- a/tests/testthat/test-ggsave.R +++ b/tests/testthat/test-ggsave.R @@ -1,5 +1,3 @@ -context("ggsave") - test_that("ggsave creates file", { path <- tempfile() on.exit(unlink(path)) diff --git a/tests/testthat/test-grid-utils.R b/tests/testthat/test-grid-utils.R index 2b8944b043..f9f018953e 100644 --- a/tests/testthat/test-grid-utils.R +++ b/tests/testthat/test-grid-utils.R @@ -1,5 +1,3 @@ -context("Grid utilites") - test_that("width_cm and height_cm work with unit arithmetic", { x <- 2 * unit(1, "cm") diff --git a/tests/testthat/test-guides.R b/tests/testthat/test-guides.R index 541b4f3d29..c65f649794 100644 --- a/tests/testthat/test-guides.R +++ b/tests/testthat/test-guides.R @@ -1,5 +1,3 @@ -context("Guides") - skip_on_cran() # This test suite is long-running (on cran) and is skipped test_that("colourbar trains without labels", { @@ -60,7 +58,7 @@ test_that("axis_label_overlap_priority always returns the correct number of elem }) test_that("axis_label_element_overrides errors when angles are outside the range [0, 90]", { - expect_is(axis_label_element_overrides("bottom", 0), "element") + expect_s3_class(axis_label_element_overrides("bottom", 0), "element") expect_error(axis_label_element_overrides("bottom", 91), "`angle` must") expect_error(axis_label_element_overrides("bottom", -91), "`angle` must") }) @@ -89,7 +87,12 @@ test_that("a warning is generated when more than one position guide is drawn at y.sec = guide_axis(position = "left") ) built <- expect_silent(ggplot_build(plot)) - expect_warning(ggplot_gtable(built), "Discarding guide") + + # TODO: These multiple warnings should be summarized nicely. Until this gets + # fixed, this test ignores all the following errors than the first one. + suppressWarnings( + expect_warning(ggplot_gtable(built), "Discarding guide") + ) }) test_that("a warning is not generated when properly changing the position of a guide_axis()", { diff --git a/tests/testthat/test-labellers.R b/tests/testthat/test-labellers.R index 5900e31e4e..dd6fa90ca7 100644 --- a/tests/testthat/test-labellers.R +++ b/tests/testthat/test-labellers.R @@ -1,5 +1,3 @@ -context("Labellers") - test_that("label_bquote has access to functions in the calling environment", { labels <- data.frame(lab = letters[1:2]) attr(labels, "facet") <- "wrap" diff --git a/tests/testthat/test-labels.r b/tests/testthat/test-labels.r index b766e0648f..0e866fa2a4 100644 --- a/tests/testthat/test-labels.r +++ b/tests/testthat/test-labels.r @@ -1,5 +1,3 @@ -context("Labels") - test_that("setting guide labels works", { expect_identical(xlab("my label")$x, "my label") @@ -27,16 +25,16 @@ test_that("setting guide labels works", { 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 + expect_equal(labs(title = "my title"), list(title = "my title"), ignore_attr = TRUE) # formal argument + expect_equal(labs(colour = "my label"), list(colour = "my label"), ignore_attr = TRUE) # dot + expect_equal(labs(foo = "bar"), list(foo = "bar"), ignore_attr = TRUE) # 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)) + expect_equal(labs(title = NULL), list(title = NULL), ignore_attr = TRUE) # ggtitle works in the same way as labs() expect_identical(ggtitle("my title")$title, "my title") @@ -44,9 +42,10 @@ test_that("setting guide labels works", { ggtitle("my title", subtitle = "my subtitle")$subtitle, "my subtitle" ) - expect_equivalent( - ggtitle("my title", subtitle = NULL), - list(title = "my title", subtitle = NULL) + expect_equal( + unclass(ggtitle("my title", subtitle = NULL)), + list(title = "my title", subtitle = NULL), + ignore_attr = TRUE ) }) diff --git a/tests/testthat/test-layer.r b/tests/testthat/test-layer.r index e5b70eff29..ec4f60e99b 100644 --- a/tests/testthat/test-layer.r +++ b/tests/testthat/test-layer.r @@ -1,5 +1,3 @@ -context("Layer") - # Parameters -------------------------------------------------------------- test_that("aesthetics go in aes_params", { @@ -23,7 +21,7 @@ test_that("column vectors are allowed (#2609)", { df <- data_frame(x = 1:10) df$y <- scale(1:10) # Returns a column vector p <- ggplot(df, aes(x, y)) - expect_is(layer_data(p), "data.frame") + expect_s3_class(layer_data(p), "data.frame") }) test_that("missing aesthetics trigger informative error", { diff --git a/tests/testthat/test-munch.r b/tests/testthat/test-munch.r index 8fcbb20103..5c26cab9a6 100644 --- a/tests/testthat/test-munch.r +++ b/tests/testthat/test-munch.r @@ -1,5 +1,3 @@ -context("Munch") - test_that("interp works", { single_interp_test <- function(start, end, n) { i <- interp(start, end, n) diff --git a/tests/testthat/test-performance.R b/tests/testthat/test-performance.R index 5c83f2af69..3706e26cfb 100644 --- a/tests/testthat/test-performance.R +++ b/tests/testthat/test-performance.R @@ -1,5 +1,3 @@ -context("Performance related alternatives") - # modify_list() ----------------------------------------------------------- testlist <- list( diff --git a/tests/testthat/test-plot-summary-api.R b/tests/testthat/test-plot-summary-api.R index a8b2f7f5d9..2d45e990e7 100644 --- a/tests/testthat/test-plot-summary-api.R +++ b/tests/testthat/test-plot-summary-api.R @@ -1,5 +1,3 @@ -context("plot summary API") - # Note: the functions tested here are used by Shiny; please do not change # their behavior without checking with the Shiny team first. @@ -115,11 +113,11 @@ test_that("coord summary - coord_flip", { test_that("summarise_layers", { l <- summarise_layers(ggplot_build(p)) - expect_equal(l$mapping[[1]], list(x = quo(displ), y = quo(hwy))) + expect_equal(l$mapping[[1]], list(x = quo(displ), y = quo(hwy)), ignore_attr = TRUE) p2 <- p + geom_point(aes(x = displ/2, y = hwy/2)) l2 <- summarise_layers(ggplot_build(p2)) - expect_equal(l2$mapping[[1]], list(x = quo(displ), y = quo(hwy))) + expect_equal(l2$mapping[[1]], list(x = quo(displ), y = quo(hwy)), ignore_attr = TRUE) # Here use _identical because the quosures are supposed to be local expect_identical(l2$mapping[[2]], list(x = quo(displ/2), y = quo(hwy/2))) diff --git a/tests/testthat/test-position-dodge2.R b/tests/testthat/test-position-dodge2.R index 08aa70082f..4f5fcf90dc 100644 --- a/tests/testthat/test-position-dodge2.R +++ b/tests/testthat/test-position-dodge2.R @@ -1,5 +1,3 @@ -context("position_dodge2") - test_that("find_x_overlaps identifies overlapping groups", { df1 <- data_frame( diff --git a/tests/testthat/test-position-nudge.R b/tests/testthat/test-position-nudge.R index fa634aa95c..2ec0e767e2 100644 --- a/tests/testthat/test-position-nudge.R +++ b/tests/testthat/test-position-nudge.R @@ -1,5 +1,3 @@ -context("position_nudge") - test_that("nudging works in both dimensions simultaneously", { # individual nudge value df <- data_frame(x = 1:3) diff --git a/tests/testthat/test-position-stack.R b/tests/testthat/test-position-stack.R index 492c850570..0243f0edd9 100644 --- a/tests/testthat/test-position-stack.R +++ b/tests/testthat/test-position-stack.R @@ -1,5 +1,3 @@ -context("position_stack") - test_that("data keeps its order after stacking", { df <- data_frame( x = rep(c(1:10), 3), diff --git a/tests/testthat/test-position_dodge.R b/tests/testthat/test-position_dodge.R index ef93727763..4d540176ad 100644 --- a/tests/testthat/test-position_dodge.R +++ b/tests/testthat/test-position_dodge.R @@ -1,5 +1,3 @@ -context("position_dodge") - test_that("can control whether to preserve total or individual width", { df <- data_frame(x = c("a", "b", "b"), y = c("a", "a", "b")) diff --git a/tests/testthat/test-prohibited-functions.R b/tests/testthat/test-prohibited-functions.R index 5fd3f17ff1..4303f48962 100644 --- a/tests/testthat/test-prohibited-functions.R +++ b/tests/testthat/test-prohibited-functions.R @@ -1,5 +1,3 @@ -context("rlang conditions") - get_n_stop <- function(f) { d <- getParseData(parse(f, keep.source = TRUE)) sum(d$token == "SYMBOL_FUNCTION_CALL" & d$text == "stop") diff --git a/tests/testthat/test-qplot.r b/tests/testthat/test-qplot.r index db56fd05d0..8e033d6397 100644 --- a/tests/testthat/test-qplot.r +++ b/tests/testthat/test-qplot.r @@ -1,16 +1,14 @@ -context("qplot") - test_that("qplot works with variables in data frame and parent env", { df <- data_frame(x = 1:10, a = 1:10) y <- 1:10 b <- 1:10 - expect_is(qplot(x, y, data = df), "ggplot") - expect_is(qplot(x, y, data = df, colour = a), "ggplot") - expect_is(qplot(x, y, data = df, colour = b), "ggplot") + expect_s3_class(qplot(x, y, data = df), "ggplot") + expect_s3_class(qplot(x, y, data = df, colour = a), "ggplot") + expect_s3_class(qplot(x, y, data = df, colour = b), "ggplot") bin <- 1 - expect_is(qplot(x, data = df, binwidth = bin), "ggplot") + expect_s3_class(qplot(x, data = df, binwidth = bin), "ggplot") }) test_that("qplot works in non-standard environments", { @@ -19,7 +17,7 @@ test_that("qplot works in non-standard environments", { x <- 1:10 qplot(x, breaks = 0:`-1-`) }) - expect_is(p, "ggplot") + expect_s3_class(p, "ggplot") }) test_that("qplot() evaluates constants in the right place", { diff --git a/tests/testthat/test-range.r b/tests/testthat/test-range.r index ee33cebaf7..6e7d6b1c6c 100644 --- a/tests/testthat/test-range.r +++ b/tests/testthat/test-range.r @@ -1,5 +1,3 @@ -context("range") - test_that("continuous ranges expand as expected", { r <- continuous_range() diff --git a/tests/testthat/test-rbind-dfs.R b/tests/testthat/test-rbind-dfs.R index a6c52b5e23..9184711911 100644 --- a/tests/testthat/test-rbind-dfs.R +++ b/tests/testthat/test-rbind-dfs.R @@ -1,5 +1,3 @@ -context("data.frame binding") - test_that("rbind_dfs keep classes of columns", { df <- data_frame( integer = seq_len(10), diff --git a/tests/testthat/test-sanitise-dim.r b/tests/testthat/test-sanitise-dim.r index 375c434ff1..b06ca31360 100644 --- a/tests/testthat/test-sanitise-dim.r +++ b/tests/testthat/test-sanitise-dim.r @@ -1,5 +1,3 @@ -context("sanitise_dim") - test_that("sanitise_dim returns NULL for zero-length inputs, with appropriate warnings", { expect_identical(sanitise_dim(NULL), NULL) n <- integer() @@ -11,10 +9,16 @@ test_that("sanitise_dim returns the first element or NULL for non-positive integ n <- 1:2 expect_identical(suppressWarnings(sanitise_dim(n)), 1L) expect_warning(sanitise_dim(n), "Only the first value of `n` will be used.") + n2 <- 0:1 - expect_identical(suppressWarnings(sanitise_dim(n2)), NULL) - expect_warning(sanitise_dim(n2), "Only the first value of `n2` will be used.") - expect_warning(sanitise_dim(n2), "`n2` is missing or less than 1 and will be treated as NULL.") + expect_warning( + expect_warning( + out <- sanitise_dim(n2), + "Only the first value of `n2` will be used." + ), + "`n2` is missing or less than 1 and will be treated as NULL." + ) + expect_identical(out, NULL) }) test_that("sanitise_dim returns a NULL for missing inputs, with appropriate warnings", { @@ -27,8 +31,14 @@ test_that("sanitise_dim returns a positive integer or NULL for non-integer input n <- 1.5 expect_identical(suppressWarnings(sanitise_dim(n)), 1L) expect_warning(sanitise_dim(n), "Coercing `n` to be an integer.") + n2 <- 0.9999999 - expect_identical(suppressWarnings(sanitise_dim(n2)), NULL) - expect_warning(sanitise_dim(n2), "Coercing `n2` to be an integer.") - expect_warning(sanitise_dim(n2), "`n2` is missing or less than 1 and will be treated as NULL.") + expect_warning( + expect_warning( + out <- sanitise_dim(n2), + "Coercing `n2` to be an integer." + ), + "`n2` is missing or less than 1 and will be treated as NULL." + ) + expect_identical(out, NULL) }) diff --git a/tests/testthat/test-scale-brewer.R b/tests/testthat/test-scale-brewer.R index 77b2c5118b..b838952fbe 100644 --- a/tests/testthat/test-scale-brewer.R +++ b/tests/testthat/test-scale-brewer.R @@ -1,5 +1,3 @@ -context("scale_brewer") - test_that("mid-point in diverging brewer color scale", { d <- data_frame(x = -1:1) diff --git a/tests/testthat/test-scale-colour-continuous.R b/tests/testthat/test-scale-colour-continuous.R index 01932b715f..364bc60a91 100644 --- a/tests/testthat/test-scale-colour-continuous.R +++ b/tests/testthat/test-scale-colour-continuous.R @@ -1,5 +1,3 @@ -context("test-scale-colour-continuous.R") - test_that("type argument is checked for proper input", { expect_error( scale_colour_continuous(type = function() "abc"), diff --git a/tests/testthat/test-scale-date.R b/tests/testthat/test-scale-date.R index dc08925bc7..8f0e1fa410 100644 --- a/tests/testthat/test-scale-date.R +++ b/tests/testthat/test-scale-date.R @@ -1,5 +1,3 @@ -context("scale_date") - base_time <- function(tz = "") { as.POSIXct(strptime("2015-06-01", "%Y-%m-%d", tz = tz)) } diff --git a/tests/testthat/test-scale-discrete.R b/tests/testthat/test-scale-discrete.R index 5d95f52dfa..d8315388ea 100644 --- a/tests/testthat/test-scale-discrete.R +++ b/tests/testthat/test-scale-discrete.R @@ -1,5 +1,3 @@ -context("scale_discrete") - # Missing values ---------------------------------------------------------- df <- tibble::tibble( diff --git a/tests/testthat/test-scale-gradient.R b/tests/testthat/test-scale-gradient.R index c1f6542829..fafa2226fe 100644 --- a/tests/testthat/test-scale-gradient.R +++ b/tests/testthat/test-scale-gradient.R @@ -1,5 +1,3 @@ -context("scale_gradient") - # Limits ------------------------------------------------------------------ test_that("points outside the limits are plotted as NA", { @@ -9,5 +7,5 @@ test_that("points outside the limits are plotted as NA", { scale_fill_gradient2(limits = c(-1, 1), midpoint = 2, na.value = "orange") correct_fill <- c("#B26D65", "#DCB4AF", "orange") - expect_equivalent(layer_data(p)$fill, correct_fill) + expect_equal(layer_data(p)$fill, correct_fill) }) diff --git a/tests/testthat/test-scale-manual.r b/tests/testthat/test-scale-manual.r index 9355558893..05da3e21d7 100644 --- a/tests/testthat/test-scale-manual.r +++ b/tests/testthat/test-scale-manual.r @@ -1,5 +1,3 @@ -context("scale_manual") - test_that("names of values used in manual scales", { s1 <- scale_colour_manual(values = c("8" = "c", "4" = "a", "6" = "b")) s1$train(c("4", "6", "8")) diff --git a/tests/testthat/test-scale-type.R b/tests/testthat/test-scale-type.R index 4504df6cd0..ccefcee95b 100644 --- a/tests/testthat/test-scale-type.R +++ b/tests/testthat/test-scale-type.R @@ -1,5 +1,3 @@ -context("test-scale-type.R") - test_that("no scale for NULL aesthetic", { expect_equal(find_scale("colour", NULL), NULL) }) diff --git a/tests/testthat/test-scale_date.R b/tests/testthat/test-scale_date.R index 02192180b9..dafd7afffe 100644 --- a/tests/testthat/test-scale_date.R +++ b/tests/testthat/test-scale_date.R @@ -1,5 +1,3 @@ -context("scale_date") - # Visual tests ------------------------------------------------------------ diff --git a/tests/testthat/test-scales-breaks-labels.r b/tests/testthat/test-scales-breaks-labels.r index 3d7c2d938f..c45540fefb 100644 --- a/tests/testthat/test-scales-breaks-labels.r +++ b/tests/testthat/test-scales-breaks-labels.r @@ -1,5 +1,3 @@ -context("Scales: breaks and labels") - test_that("labels match breaks, even when outside limits", { sc <- scale_y_continuous(breaks = 1:4, labels = 1:4, limits = c(1, 3)) @@ -99,7 +97,7 @@ test_that("discrete labels match breaks", { sc <- init_scale(breaks = 0:5 * 10) expect_equal(length(sc$get_breaks()), 5) expect_equal(length(sc$get_labels()), 5) - expect_equivalent(sc$get_labels(), sc$get_breaks()) + expect_equal(sc$get_labels(), sc$get_breaks(), ignore_attr = TRUE) sc <- init_scale(breaks = 0:5 * 10, labels = letters[1:6]) expect_equal(length(sc$get_breaks()), 5) diff --git a/tests/testthat/test-scales.r b/tests/testthat/test-scales.r index c0982662f2..308c345802 100644 --- a/tests/testthat/test-scales.r +++ b/tests/testthat/test-scales.r @@ -1,5 +1,3 @@ -context("Scales") - test_that("building a plot does not affect its scales", { dat <- data_frame(x = rnorm(20), y = rnorm(20)) @@ -354,8 +352,8 @@ test_that("scale_apply preserves class and attributes", { )[[1]], `c.baz` = `c.baz`, `[.baz` = `[.baz`, .env = global_env()) # Check class preservation - expect_is(out, "baz") - expect_is(out, "numeric") + expect_s3_class(out, "baz") + expect_s3_class(out, "numeric") # Check attribute preservation expect_identical(attr(out, "foo"), "bar") diff --git a/tests/testthat/test-sec-axis.R b/tests/testthat/test-sec-axis.R index 221d1468c9..ca75ca290e 100644 --- a/tests/testthat/test-sec-axis.R +++ b/tests/testthat/test-sec-axis.R @@ -1,5 +1,3 @@ -context("sec-axis") - x <- exp(seq(log(0.001), log(1000), length.out = 100)) foo <- data_frame( x = x, diff --git a/tests/testthat/test-stat-bin.R b/tests/testthat/test-stat-bin.R index 09f3675971..7e608e2495 100644 --- a/tests/testthat/test-stat-bin.R +++ b/tests/testthat/test-stat-bin.R @@ -1,5 +1,3 @@ -context("stat_bin/stat_count") - test_that("stat_bin throws error when y aesthetic is present", { dat <- data_frame(x = c("a", "b", "c"), y = c(1, 5, 10)) diff --git a/tests/testthat/test-stat-bin2d.R b/tests/testthat/test-stat-bin2d.R index 309136b8be..4f1d9d97bb 100644 --- a/tests/testthat/test-stat-bin2d.R +++ b/tests/testthat/test-stat-bin2d.R @@ -1,5 +1,3 @@ -context("stat_bin2d") - test_that("binwidth is respected", { df <- data_frame(x = c(1, 1, 1, 2), y = c(1, 1, 1, 2)) base <- ggplot(df, aes(x, y)) + diff --git a/tests/testthat/test-stat-boxplot.R b/tests/testthat/test-stat-boxplot.R index 7887ad7145..5e79501a95 100644 --- a/tests/testthat/test-stat-boxplot.R +++ b/tests/testthat/test-stat-boxplot.R @@ -1,5 +1,3 @@ -context("stat_boxplot") - test_that("stat_boxplot drops missing rows with a warning", { p1 <- ggplot(PlantGrowth, aes(x = group, y = weight)) + diff --git a/tests/testthat/test-stat-contour.R b/tests/testthat/test-stat-contour.R index a48a368931..c155c6c27a 100644 --- a/tests/testthat/test-stat-contour.R +++ b/tests/testthat/test-stat-contour.R @@ -1,16 +1,21 @@ - -context("stat-contour") - test_that("a warning is issued when there is more than one z per x+y", { tbl <- data_frame(x = c(1, 1, 2), y = c(1, 1, 2), z = 3) p <- ggplot(tbl, aes(x, y, z = z)) + geom_contour() - expect_warning(ggplot_build(p), "Zero contours were generated") + # Ignore other warnings than the one stat_contour() issued + suppressWarnings( + expect_warning(ggplot_build(p), "Zero contours were generated") + ) }) test_that("contouring sparse data results in a warning", { tbl <- data_frame(x = c(1, 27, 32), y = c(1, 1, 30), z = c(1, 2, 3)) p <- ggplot(tbl, aes(x, y, z = z)) + geom_contour() - expect_warning(ggplot_build(p), "Zero contours were generated") + + # TODO: These multiple warnings should be summarized nicely. Until this gets + # fixed, this test ignores all the following errors than the first one. + suppressWarnings( + expect_warning(ggplot_build(p), "Zero contours were generated") + ) }) test_that("contouring irregularly spaced data works", { diff --git a/tests/testthat/test-stat-density.R b/tests/testthat/test-stat-density.R index 4a26927a0c..9cc9e7a6aa 100644 --- a/tests/testthat/test-stat-density.R +++ b/tests/testthat/test-stat-density.R @@ -1,5 +1,3 @@ -context("stat_density") # and stat_ydensity - test_that("compute_density succeeds when variance is zero", { dens <- compute_density(rep(0, 10), NULL, from = 0.5, to = 0.5) expect_equal(dens$n, rep(10, 512)) diff --git a/tests/testthat/test-stat-density2d.R b/tests/testthat/test-stat-density2d.R index 3ac5494c90..8446feaf49 100644 --- a/tests/testthat/test-stat-density2d.R +++ b/tests/testthat/test-stat-density2d.R @@ -1,5 +1,3 @@ -context("stat_density_2d") - test_that("uses scale limits, not data limits", { base <- ggplot(mtcars, aes(wt, mpg)) + stat_density_2d() + diff --git a/tests/testthat/test-stat-ecdf.R b/tests/testthat/test-stat-ecdf.R index 4e56e3625b..6c0a8d7e4d 100644 --- a/tests/testthat/test-stat-ecdf.R +++ b/tests/testthat/test-stat-ecdf.R @@ -1,5 +1,3 @@ -context("stat_ecdf") - test_that("stat_ecdf works in both directions", { p <- ggplot(mpg, aes(hwy)) + stat_ecdf() x <- layer_data(p) diff --git a/tests/testthat/test-stat-ellipsis.R b/tests/testthat/test-stat-ellipsis.R index 6c1dcf8fdb..95a5df9ad7 100644 --- a/tests/testthat/test-stat-ellipsis.R +++ b/tests/testthat/test-stat-ellipsis.R @@ -1,5 +1,3 @@ -context("stat_ellipsis") - test_that("stat_ellipsis returns correct data format", { n_seg <- 40 d <- data_frame(x = c(1, 1, 4, 4, 4, 3, 3, 1), y = c(1:4, 1:4), id = rep(1:2, each = 4)) diff --git a/tests/testthat/test-stat-function.R b/tests/testthat/test-stat-function.R index 861d88df15..fbe4f38b7e 100644 --- a/tests/testthat/test-stat-function.R +++ b/tests/testthat/test-stat-function.R @@ -1,5 +1,3 @@ -context("stat_function") - test_that("uses scale limits, not data limits", { dat <- data_frame(x = c(0.1, 1:100)) dat$y <- dexp(dat$x) diff --git a/tests/testthat/test-stat-hex.R b/tests/testthat/test-stat-hex.R index 1ae9a5fc63..3f9959992b 100644 --- a/tests/testthat/test-stat-hex.R +++ b/tests/testthat/test-stat-hex.R @@ -1,5 +1,3 @@ -context("stat_hex") - test_that("can use length 1 binwidth", { df <- data_frame(x = c(1, 1, 2), y = c(1, 1, 2)) p <- ggplot(df, aes(x, y)) + stat_binhex(binwidth = 1) diff --git a/tests/testthat/test-stat-sf-coordinates.R b/tests/testthat/test-stat-sf-coordinates.R index f328af194e..e7fa887eb5 100644 --- a/tests/testthat/test-stat-sf-coordinates.R +++ b/tests/testthat/test-stat-sf-coordinates.R @@ -1,5 +1,3 @@ -context("stat_sf_coordinates") - comp_sf_coord <- function(df, ...) { plot <- ggplot(df) + stat_sf_coordinates(...) layer_data(plot) diff --git a/tests/testthat/test-stat-sum.R b/tests/testthat/test-stat-sum.R index d62584e61d..43734a0961 100644 --- a/tests/testthat/test-stat-sum.R +++ b/tests/testthat/test-stat-sum.R @@ -1,5 +1,3 @@ -context("stat_sum") - test_that("handles grouping correctly", { d <- diamonds[1:1000, ] all_ones <- function(x) all.equal(mean(x), 1) diff --git a/tests/testthat/test-stat-summary.R b/tests/testthat/test-stat-summary.R index 1c4b29a166..5f8cc4b4fd 100644 --- a/tests/testthat/test-stat-summary.R +++ b/tests/testthat/test-stat-summary.R @@ -1,5 +1,3 @@ -context("stat_summary") - test_that("stat_summary(_bin) work with lambda expressions", { # note: stat_summary and stat_summary_bin both use # make_summary_fun, so this tests both diff --git a/tests/testthat/test-stats.r b/tests/testthat/test-stats.r index a4be7921df..01b94a6635 100644 --- a/tests/testthat/test-stats.r +++ b/tests/testthat/test-stats.r @@ -1,5 +1,3 @@ -context("Stats") - test_that("plot succeeds even if some computation fails", { df <- data_frame(x = 1:2, y = 1) p1 <- ggplot(df, aes(x, y)) + geom_point() @@ -8,7 +6,12 @@ test_that("plot succeeds even if some computation fails", { expect_equal(length(b1$data), 1) p2 <- p1 + geom_smooth() - expect_warning(b2 <- ggplot_build(p2), "Computation failed") + + # TODO: These multiple warnings should be summarized nicely. Until this gets + # fixed, this test ignores all the following errors than the first one. + suppressWarnings( + expect_warning(b2 <- ggplot_build(p2), "Computation failed") + ) expect_equal(length(b2$data), 2) }) diff --git a/tests/testthat/test-theme.r b/tests/testthat/test-theme.r index dd06008505..1406de6ce3 100644 --- a/tests/testthat/test-theme.r +++ b/tests/testthat/test-theme.r @@ -1,5 +1,3 @@ -context("Themes") - skip_on_cran() # This test suite is long-running (on cran) and is skipped test_that("modifying theme element properties with + operator works", { diff --git a/tests/testthat/test-utilities.r b/tests/testthat/test-utilities.r index e0c07e458c..7970ec5791 100644 --- a/tests/testthat/test-utilities.r +++ b/tests/testthat/test-utilities.r @@ -1,5 +1,3 @@ -context("Utilities") - test_that("finite_cases.data.frame", { finite_cases <- function(x) cases(x, is_finite) diff --git a/tests/testthat/test-viridis.R b/tests/testthat/test-viridis.R index 8b4fb1e758..31dad3f3bb 100644 --- a/tests/testthat/test-viridis.R +++ b/tests/testthat/test-viridis.R @@ -1,5 +1,3 @@ -context("Viridis") - df <- data_frame(x = 1, y = 1, z = "a", tier = factor("low", ordered = TRUE)) test_that("viridis scale changes point color", { diff --git a/tests/testthat/test-zzz.R b/tests/testthat/test-zzz.R index 8f5ade9868..539cd88767 100644 --- a/tests/testthat/test-zzz.R +++ b/tests/testthat/test-zzz.R @@ -1,5 +1,3 @@ -context("zzz") - test_that(".onAttach does not modify the random stream", { set.seed(42) x <- runif(5) From cad7f78e53b38cdcb60ff6ffb4ace63349c698f9 Mon Sep 17 00:00:00 2001 From: Jake Russ Date: Tue, 9 Nov 2021 03:22:00 -0500 Subject: [PATCH 15/32] Add arrow to line params (#4659) --- NEWS.md | 2 + R/geom-sf.R | 10 ++- ...-carolina-county-boundaries-with-arrow.svg | 72 ++++++++++++++++ ...ty-boundaries-with-more-than-one-arrow.svg | 82 +++++++++++++++++++ tests/testthat/test-geom-sf.R | 35 ++++++++ 5 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-arrow.svg create mode 100644 tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-more-than-one-arrow.svg diff --git a/NEWS.md b/NEWS.md index fe7fef0b0d..0f6c3ac992 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 (development version) +* `geom_sf()` now respects `arrow` parameter for lines (@jakeruss, #4659) + * Updated documentation for `print.ggplot` to reflect that it returns the original plot, not the result of `ggplot_build()`. (@r2evans, #4390) diff --git a/R/geom-sf.R b/R/geom-sf.R index 4367ade3be..0111c6fd5b 100644 --- a/R/geom-sf.R +++ b/R/geom-sf.R @@ -128,14 +128,15 @@ GeomSf <- ggproto("GeomSf", Geom, draw_panel = function(data, panel_params, coord, legend = NULL, lineend = "butt", linejoin = "round", linemitre = 10, - na.rm = TRUE) { + arrow = NULL, na.rm = TRUE) { if (!inherits(coord, "CoordSf")) { abort("geom_sf() must be used with coord_sf()") } # Need to refactor this to generate one grob per geometry type coord <- coord$transform(data, panel_params) - sf_grob(coord, lineend = lineend, linejoin = linejoin, linemitre = linemitre, na.rm = na.rm) + sf_grob(coord, lineend = lineend, linejoin = linejoin, linemitre = linemitre, + arrow = arrow, na.rm = na.rm) }, draw_key = function(data, params, size) { @@ -160,7 +161,8 @@ default_aesthetics <- function(type) { } } -sf_grob <- function(x, lineend = "butt", linejoin = "round", linemitre = 10, na.rm = TRUE) { +sf_grob <- function(x, lineend = "butt", linejoin = "round", linemitre = 10, + arrow = NULL, na.rm = TRUE) { type <- sf_types[sf::st_geometry_type(x$geometry)] is_point <- type == "point" is_line <- type == "line" @@ -210,7 +212,7 @@ sf_grob <- function(x, lineend = "butt", linejoin = "round", linemitre = 10, na. col = col, fill = fill, fontsize = fontsize, lwd = lwd, lty = lty, lineend = lineend, linejoin = linejoin, linemitre = linemitre ) - sf::st_as_grob(x$geometry, pch = pch, gp = gp) + sf::st_as_grob(x$geometry, pch = pch, gp = gp, arrow = arrow) } #' @export diff --git a/tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-arrow.svg b/tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-arrow.svg new file mode 100644 index 0000000000..48beafdcdd --- /dev/null +++ b/tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-arrow.svg @@ -0,0 +1,72 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +36.25 +36.30 +36.35 +36.40 +36.45 +36.50 +36.55 +36.60 + + + + + + + + + + + + + +-81.7 +-81.6 +-81.5 +-81.4 +-81.3 +North Carolina county boundaries with arrow + + diff --git a/tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-more-than-one-arrow.svg b/tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-more-than-one-arrow.svg new file mode 100644 index 0000000000..165452b12f --- /dev/null +++ b/tests/testthat/_snaps/geom-sf/north-carolina-county-boundaries-with-more-than-one-arrow.svg @@ -0,0 +1,82 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +36.25 +36.30 +36.35 +36.40 +36.45 +36.50 +36.55 +36.60 + + + + + + + + + + + + + +-81.7 +-81.6 +-81.5 +-81.4 +-81.3 +North Carolina county boundaries with more than one arrow + + diff --git a/tests/testthat/test-geom-sf.R b/tests/testthat/test-geom-sf.R index d3c5acc91f..ded534a0d2 100644 --- a/tests/testthat/test-geom-sf.R +++ b/tests/testthat/test-geom-sf.R @@ -200,3 +200,38 @@ test_that("geom_sf_text() and geom_sf_label() draws correctly", { ggplot() + geom_sf_label(data = nc_3857, aes(label = NAME)) ) }) + +test_that("geom_sf draws arrows correctly", { + skip_if_not_installed("sf") + if (packageVersion("sf") < "0.5.3") skip("Need sf 0.5.3") + + nc_tiny_coords <- data_frame( + x = c(-81.473, -81.741, -81.67, -81.345, -81.266, -81.24, -81.473), + y = c(36.234, 36.392, 36.59, 36.573, 36.437, 36.365, 36.234) + ) + + nc <- sf::st_linestring( + sf::st_coordinates(sf::st_as_sf(nc_tiny_coords, coords = c("x", "y"), crs = 4326)) + ) + + nc2 <- sf::st_cast( + sf::st_sfc( + sf::st_multilinestring(lapply( + 1:(length(sf::st_coordinates(nc)[, 1]) - 1), + function(x) rbind( + as.numeric(sf::st_coordinates(nc)[x, 1:2]), + as.numeric(sf::st_coordinates(nc)[x + 1, 1:2]) + ) + ) + ), sf::st_crs(nc) + ), "LINESTRING" + ) + + expect_doppelganger("North Carolina county boundaries with arrow", + ggplot() + geom_sf(data = nc, arrow = arrow()) + coord_sf(datum = 4326) + ) + + expect_doppelganger("North Carolina county boundaries with more than one arrow", + ggplot() + geom_sf(data = nc2, arrow = arrow()) + coord_sf(datum = 4326) + ) +}) From aaaec2ff3a575ba42b7b0cee59d34597bd42f040 Mon Sep 17 00:00:00 2001 From: Hugo Gruson Date: Tue, 9 Nov 2021 08:55:39 +0000 Subject: [PATCH 16/32] Add example showing how to use the fill argument in stat_function() (#4420) --- R/geom-function.R | 2 ++ man/geom_function.Rd | 2 ++ 2 files changed, 4 insertions(+) diff --git a/R/geom-function.R b/R/geom-function.R index 98fba891fc..30b58d8426 100644 --- a/R/geom-function.R +++ b/R/geom-function.R @@ -32,6 +32,8 @@ #' #' base + stat_function(fun = dnorm, geom = "point", n = 20) #' +#' base + stat_function(fun = dnorm, geom = "polygon", color = "blue", fill = "blue", alpha = 0.5) +#' #' base + geom_function(fun = dnorm, n = 20) #' #' # Two functions on the same plot diff --git a/man/geom_function.Rd b/man/geom_function.Rd index bcc0d61538..053808f93f 100644 --- a/man/geom_function.Rd +++ b/man/geom_function.Rd @@ -130,6 +130,8 @@ base + stat_function(fun = dnorm, geom = "point") base + stat_function(fun = dnorm, geom = "point", n = 20) +base + stat_function(fun = dnorm, geom = "polygon", color = "blue", fill = "blue", alpha = 0.5) + base + geom_function(fun = dnorm, n = 20) # Two functions on the same plot From 6704ea1fd01369445e7d28946edb8312c133691d Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Wed, 10 Nov 2021 15:39:07 +0100 Subject: [PATCH 17/32] Consistent use of lineend and linejoin in geoms and keys (#4664) --- NEWS.md | 3 + R/geom-abline.r | 4 +- R/geom-bar.r | 11 +- R/geom-boxplot.r | 22 ++- R/geom-col.r | 11 +- R/geom-crossbar.r | 8 +- R/geom-dotplot.r | 5 +- R/geom-errorbar.r | 4 +- R/geom-errorbarh.r | 4 +- R/geom-hex.r | 8 +- R/geom-hline.r | 4 +- R/geom-linerange.r | 4 +- R/geom-map.r | 11 +- R/geom-pointrange.r | 6 +- R/geom-polygon.r | 13 +- R/geom-rect.r | 8 +- R/geom-ribbon.r | 15 +- R/geom-rug.r | 10 +- R/geom-smooth.r | 5 +- R/geom-violin.r | 2 +- R/geom-vline.r | 4 +- R/legend-draw.r | 27 +-- .../_snaps/aes/stat-count-width-0-5.svg | 6 +- tests/testthat/_snaps/aes/stat-count.svg | 6 +- .../_snaps/aes/stat-identity-width-0-5.svg | 6 +- tests/testthat/_snaps/aes/stat-identity.svg | 6 +- .../coord-map-switched-scale-position.svg | 20 +- .../_snaps/coord-map/usa-mercator.svg | 20 +- ...etrack-plot-closed-and-has-center-hole.svg | 6 +- ...cetrack-plot-closed-and-no-center-hole.svg | 6 +- .../rose-plot-with-has-equal-spacing.svg | 6 +- .../rectangle-and-dotplot-key-glyphs.svg | 6 +- .../time-series-and-polygon-key-glyphs.svg | 6 +- .../_snaps/geom-boxplot/outlier-colours.svg | 36 ++-- .../2-na-values-bin-along-y-stack-center.svg | 36 ++-- ...-values-dot-density-binning-binwidth-4.svg | 36 ++-- .../3-stackgroups-bin-y-histodot.svg | 186 +++++++++--------- ...ckgroups-dot-density-with-aligned-bins.svg | 186 +++++++++--------- .../geom-dotplot/3-stackgroups-histodot.svg | 186 +++++++++--------- ...ot-with-dot-density-binning-binwidth-4.svg | 40 ++-- .../geom-dotplot/bin-along-y-stack-center.svg | 40 ++-- ...bin-along-y-stack-centerwhole-histodot.svg | 40 ++-- .../bin-along-y-stack-centerwhole.svg | 40 ++-- .../bin-y-continous-x-axis-grouping-by-x.svg | 180 ++++++++--------- .../bin-y-continous-x-axis-single-x-group.svg | 180 ++++++++--------- .../geom-dotplot/bin-y-dodged-coord-flip.svg | 186 +++++++++--------- .../_snaps/geom-dotplot/bin-y-dodged.svg | 186 +++++++++--------- .../bin-y-dodging-3-stackgroups-histodot.svg | 184 ++++++++--------- ...ee-x-groups-bins-aligned-across-groups.svg | 180 ++++++++--------- ...three-x-groups-bins-aligned-coord-flip.svg | 180 ++++++++--------- .../bin-y-three-x-groups-fill-and-dodge.svg | 184 ++++++++--------- ...bin-y-three-x-groups-stack-centerwhole.svg | 180 ++++++++--------- ...stacked-closer-stackratio-5-fill-white.svg | 40 ++-- .../facets-3-groups-histodot-stackgroups.svg | 184 ++++++++--------- .../histodot-binning-equal-bin-spacing.svg | 40 ++-- .../larger-dots-dotsize-1-5-fill-white.svg | 40 ++-- .../multiple-groups-bins-aligned.svg | 44 ++--- .../multiple-groups-bins-not-aligned.svg | 44 ++--- .../stack-center-with-coord-flip.svg | 40 ++-- .../_snaps/geom-dotplot/stack-center.svg | 40 ++-- .../stack-centerwhole-with-coord-flip.svg | 40 ++-- .../_snaps/geom-dotplot/stack-centerwhole.svg | 40 ++-- .../stack-down-with-coord-flip.svg | 40 ++-- .../_snaps/geom-dotplot/stack-down.svg | 40 ++-- .../geom-dotplot/stack-up-with-coord-flip.svg | 40 ++-- .../testthat/_snaps/geom-dotplot/stack-up.svg | 40 ++-- ...etype-and-size-specified-as-aesthetics.svg | 54 ++--- .../cartesian-lines-intersect-mid-bars.svg | 10 +- .../flipped-lines-intersect-mid-bars.svg | 10 +- .../polar-lines-intersect-mid-bars.svg | 10 +- .../geom-polygon/basic-polygon-plot.svg | 4 +- .../ribbon-turned-on-in-geom-smooth.svg | 12 +- tests/testthat/_snaps/geom-violin/basic.svg | 6 +- ...is-many-groups-center-should-be-at-2-0.svg | 2 +- ...s-single-group-center-should-be-at-1-0.svg | 2 +- .../_snaps/geom-violin/coord-flip.svg | 6 +- .../_snaps/geom-violin/coord-polar.svg | 6 +- .../geom-violin/dodging-and-coord-flip.svg | 12 +- tests/testthat/_snaps/geom-violin/dodging.svg | 12 +- ...grouping-on-x-and-fill-dodge-width-0-5.svg | 16 +- .../geom-violin/grouping-on-x-and-fill.svg | 16 +- .../_snaps/geom-violin/narrower-width-5.svg | 6 +- .../testthat/_snaps/geom-violin/quantiles.svg | 6 +- ...scale-area-to-sample-size-c-is-smaller.svg | 6 +- .../with-smaller-bandwidth-and-points.svg | 6 +- .../geom-violin/with-tails-and-points.svg | 6 +- ...e-plot-bottom-left-of-legend-at-center.svg | 12 +- .../guides/legend-inside-plot-bottom-left.svg | 12 +- .../guides/legend-inside-plot-centered.svg | 12 +- .../guides/legend-inside-plot-top-right.svg | 12 +- .../_snaps/guides/padding-in-legend-box.svg | 12 +- .../_snaps/position-stack/area-stacking.svg | 12 +- .../functional-limits.svg | 30 +-- ...summary-with-crossbars-manual-grouping.svg | 12 +- .../summary-with-crossbars-no-grouping.svg | 12 +- 95 files changed, 1929 insertions(+), 1866 deletions(-) diff --git a/NEWS.md b/NEWS.md index 0f6c3ac992..e8b0c809ff 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* All geoms now have consistent exposure of linejoin and lineend parameters, and + the guide keys will now respect these settings (@thomasp85, #4653) + * `geom_sf()` now respects `arrow` parameter for lines (@jakeruss, #4659) * Updated documentation for `print.ggplot` to reflect that it returns diff --git a/R/geom-abline.r b/R/geom-abline.r index 35b53ce57f..9778e76386 100644 --- a/R/geom-abline.r +++ b/R/geom-abline.r @@ -124,7 +124,7 @@ geom_abline <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomAbline <- ggproto("GeomAbline", Geom, - draw_panel = function(data, panel_params, coord) { + draw_panel = function(data, panel_params, coord, lineend = "butt") { ranges <- coord$backtransform_range(panel_params) if (coord$clip == "on" && coord$is_linear()) { @@ -138,7 +138,7 @@ GeomAbline <- ggproto("GeomAbline", Geom, data$y <- ranges$x[1] * data$slope + data$intercept data$yend <- ranges$x[2] * data$slope + data$intercept - GeomSegment$draw_panel(unique(data), panel_params, coord) + GeomSegment$draw_panel(unique(data), panel_params, coord, lineend = lineend) }, default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), diff --git a/R/geom-bar.r b/R/geom-bar.r index 54fc35684e..68d22f0b8b 100644 --- a/R/geom-bar.r +++ b/R/geom-bar.r @@ -137,8 +137,15 @@ GeomBar <- ggproto("GeomBar", GeomRect, flip_data(data, params$flipped_aes) }, - draw_panel = function(self, data, panel_params, coord, width = NULL, flipped_aes = FALSE) { + draw_panel = function(self, data, panel_params, coord, lineend = "butt", + linejoin = "mitre", width = NULL, flipped_aes = FALSE) { # Hack to ensure that width is detected as a parameter - ggproto_parent(GeomRect, self)$draw_panel(data, panel_params, coord) + ggproto_parent(GeomRect, self)$draw_panel( + data, + panel_params, + coord, + lineend = lineend, + linejoin = linejoin + ) } ) diff --git a/R/geom-boxplot.r b/R/geom-boxplot.r index 4a2d44ce88..e90211b251 100644 --- a/R/geom-boxplot.r +++ b/R/geom-boxplot.r @@ -205,12 +205,12 @@ GeomBoxplot <- ggproto("GeomBoxplot", Geom, flip_data(data, params$flipped_aes) }, - draw_group = function(data, panel_params, coord, fatten = 2, - outlier.colour = NULL, outlier.fill = NULL, - outlier.shape = 19, + draw_group = function(data, panel_params, coord, lineend = "butt", + linejoin = "mitre", fatten = 2, outlier.colour = NULL, + outlier.fill = NULL, outlier.shape = 19, outlier.size = 1.5, outlier.stroke = 0.5, - outlier.alpha = NULL, - notch = FALSE, notchwidth = 0.5, varwidth = FALSE, flipped_aes = FALSE) { + outlier.alpha = NULL, notch = FALSE, notchwidth = 0.5, + varwidth = FALSE, flipped_aes = FALSE) { data <- flip_data(data, flipped_aes) # this may occur when using geom_boxplot(stat = "identity") if (nrow(data) != 1) { @@ -274,8 +274,16 @@ GeomBoxplot <- ggproto("GeomBoxplot", Geom, ggname("geom_boxplot", grobTree( outliers_grob, - GeomSegment$draw_panel(whiskers, panel_params, coord), - GeomCrossbar$draw_panel(box, fatten = fatten, panel_params, coord, flipped_aes = flipped_aes) + GeomSegment$draw_panel(whiskers, panel_params, coord, lineend = lineend), + GeomCrossbar$draw_panel( + box, + fatten = fatten, + panel_params, + coord, + lineend = lineend, + linejoin = linejoin, + flipped_aes = flipped_aes + ) )) }, diff --git a/R/geom-col.r b/R/geom-col.r index be91cfc480..510e57c9d8 100644 --- a/R/geom-col.r +++ b/R/geom-col.r @@ -56,8 +56,15 @@ GeomCol <- ggproto("GeomCol", GeomRect, flip_data(data, params$flipped_aes) }, - draw_panel = function(self, data, panel_params, coord, width = NULL, flipped_aes = FALSE) { + draw_panel = function(self, data, panel_params, coord, lineend = "butt", + linejoin = "mitre", width = NULL, flipped_aes = FALSE) { # Hack to ensure that width is detected as a parameter - ggproto_parent(GeomRect, self)$draw_panel(data, panel_params, coord) + ggproto_parent(GeomRect, self)$draw_panel( + data, + panel_params, + coord, + lineend = lineend, + linejoin = linejoin + ) } ) diff --git a/R/geom-crossbar.r b/R/geom-crossbar.r index 05fa058460..89c1c60cff 100644 --- a/R/geom-crossbar.r +++ b/R/geom-crossbar.r @@ -47,7 +47,9 @@ GeomCrossbar <- ggproto("GeomCrossbar", Geom, draw_key = draw_key_crossbar, - draw_panel = function(data, panel_params, coord, fatten = 2.5, width = NULL, flipped_aes = FALSE) { + draw_panel = function(data, panel_params, coord, lineend = "butt", + linejoin = "mitre", fatten = 2.5, width = NULL, + flipped_aes = FALSE) { data <- flip_data(data, flipped_aes) middle <- transform(data, x = xmin, xend = xmax, yend = y, size = size * fatten, alpha = NA) @@ -99,8 +101,8 @@ GeomCrossbar <- ggproto("GeomCrossbar", Geom, middle <- flip_data(middle, flipped_aes) ggname("geom_crossbar", gTree(children = gList( - GeomPolygon$draw_panel(box, panel_params, coord), - GeomSegment$draw_panel(middle, panel_params, coord) + GeomPolygon$draw_panel(box, panel_params, coord, lineend = lineend, linejoin = linejoin), + GeomSegment$draw_panel(middle, panel_params, coord, lineend = lineend, linejoin = linejoin) ))) } ) diff --git a/R/geom-dotplot.r b/R/geom-dotplot.r index 9b34e517f1..e866e834a0 100644 --- a/R/geom-dotplot.r +++ b/R/geom-dotplot.r @@ -264,7 +264,7 @@ GeomDotplot <- ggproto("GeomDotplot", Geom, }, - draw_group = function(data, panel_params, coord, na.rm = FALSE, + draw_group = function(data, panel_params, coord, lineend = "butt", na.rm = FALSE, binaxis = "x", stackdir = "up", stackratio = 1, dotsize = 1, stackgroups = FALSE) { if (!coord$is_linear()) { @@ -292,7 +292,8 @@ GeomDotplot <- ggproto("GeomDotplot", Geom, default.units = "npc", gp = gpar(col = alpha(tdata$colour, tdata$alpha), fill = alpha(tdata$fill, tdata$alpha), - lwd = tdata$stroke, lty = tdata$linetype)) + lwd = tdata$stroke, lty = tdata$linetype, + lineend = lineend)) ) }, diff --git a/R/geom-errorbar.r b/R/geom-errorbar.r index 4840d75d10..dd2cfd5551 100644 --- a/R/geom-errorbar.r +++ b/R/geom-errorbar.r @@ -52,7 +52,7 @@ GeomErrorbar <- ggproto("GeomErrorbar", Geom, flip_data(data, params$flipped_aes) }, - draw_panel = function(data, panel_params, coord, width = NULL, flipped_aes = FALSE) { + draw_panel = function(data, panel_params, coord, lineend = "butt", width = NULL, flipped_aes = FALSE) { data <- flip_data(data, flipped_aes) x <- as.vector(rbind(data$xmin, data$xmax, NA, data$x, data$x, NA, data$xmin, data$xmax)) y <- as.vector(rbind(data$ymax, data$ymax, NA, data$ymax, data$ymin, NA, data$ymin, data$ymin)) @@ -67,6 +67,6 @@ GeomErrorbar <- ggproto("GeomErrorbar", Geom, row.names = 1:(nrow(data) * 8) )) data <- flip_data(data, flipped_aes) - GeomPath$draw_panel(data, panel_params, coord) + GeomPath$draw_panel(data, panel_params, coord, lineend = lineend) } ) diff --git a/R/geom-errorbarh.r b/R/geom-errorbarh.r index 7c48dd9f5c..91d3569e86 100644 --- a/R/geom-errorbarh.r +++ b/R/geom-errorbarh.r @@ -67,7 +67,7 @@ GeomErrorbarh <- ggproto("GeomErrorbarh", Geom, ) }, - draw_panel = function(data, panel_params, coord, height = NULL) { + draw_panel = function(data, panel_params, coord, height = NULL, lineend = "butt") { GeomPath$draw_panel(new_data_frame(list( x = as.vector(rbind(data$xmax, data$xmax, NA, data$xmax, data$xmin, NA, data$xmin, data$xmin)), y = as.vector(rbind(data$ymin, data$ymax, NA, data$y, data$y, NA, data$ymin, data$ymax)), @@ -77,6 +77,6 @@ GeomErrorbarh <- ggproto("GeomErrorbarh", Geom, linetype = rep(data$linetype, each = 8), group = rep(1:(nrow(data)), each = 8), row.names = 1:(nrow(data) * 8) - )), panel_params, coord) + )), panel_params, coord, lineend = lineend) } ) diff --git a/R/geom-hex.r b/R/geom-hex.r index 6879038724..2e18b221e9 100644 --- a/R/geom-hex.r +++ b/R/geom-hex.r @@ -54,7 +54,8 @@ geom_hex <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomHex <- ggproto("GeomHex", Geom, - draw_group = function(data, panel_params, coord) { + draw_group = function(data, panel_params, coord, lineend = "butt", + linejoin = "mitre", linemitre = 10) { if (!inherits(coord, "CoordCartesian")) { abort("geom_hex() only works with Cartesian coordinates") } @@ -66,7 +67,10 @@ GeomHex <- ggproto("GeomHex", Geom, col = coords$colour, fill = alpha(coords$fill, coords$alpha), lwd = coords$size * .pt, - lty = coords$linetype + lty = coords$linetype, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre ) )) }, diff --git a/R/geom-hline.r b/R/geom-hline.r index d242f74b08..8e0151d012 100644 --- a/R/geom-hline.r +++ b/R/geom-hline.r @@ -44,7 +44,7 @@ geom_hline <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomHline <- ggproto("GeomHline", Geom, - draw_panel = function(data, panel_params, coord) { + draw_panel = function(data, panel_params, coord, lineend = "butt") { ranges <- coord$backtransform_range(panel_params) data$x <- ranges$x[1] @@ -52,7 +52,7 @@ GeomHline <- ggproto("GeomHline", Geom, data$y <- data$yintercept data$yend <- data$yintercept - GeomSegment$draw_panel(unique(data), panel_params, coord) + GeomSegment$draw_panel(unique(data), panel_params, coord, lineend = lineend) }, default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), diff --git a/R/geom-linerange.r b/R/geom-linerange.r index 005f93de3a..5e9462013b 100644 --- a/R/geom-linerange.r +++ b/R/geom-linerange.r @@ -113,10 +113,10 @@ GeomLinerange <- ggproto("GeomLinerange", Geom, data }, - draw_panel = function(data, panel_params, coord, flipped_aes = FALSE) { + draw_panel = function(data, panel_params, coord, lineend = "butt", flipped_aes = FALSE) { data <- flip_data(data, flipped_aes) data <- transform(data, xend = x, y = ymin, yend = ymax) data <- flip_data(data, flipped_aes) - ggname("geom_linerange", GeomSegment$draw_panel(data, panel_params, coord)) + ggname("geom_linerange", GeomSegment$draw_panel(data, panel_params, coord, lineend = lineend)) } ) diff --git a/R/geom-map.r b/R/geom-map.r index 031e0c5b91..8690063fd3 100644 --- a/R/geom-map.r +++ b/R/geom-map.r @@ -105,7 +105,8 @@ geom_map <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomMap <- ggproto("GeomMap", GeomPolygon, - draw_panel = function(data, panel_params, coord, map) { + draw_panel = function(data, panel_params, coord, lineend = "butt", + linejoin = "round", linemitre = 10, map) { # Only use matching data and map ids common <- intersect(data$map_id, map$id) data <- data[data$map_id %in% common, , drop = FALSE] @@ -123,8 +124,12 @@ GeomMap <- ggproto("GeomMap", GeomPolygon, polygonGrob(coords$x, coords$y, default.units = "native", id = grob_id, gp = gpar( - col = data$colour, fill = alpha(data$fill, data$alpha), - lwd = data$size * .pt + col = data$colour, + fill = alpha(data$fill, data$alpha), + lwd = data$size * .pt, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre ) ) }, diff --git a/R/geom-pointrange.r b/R/geom-pointrange.r index 5b018c1253..834a4f9f8a 100644 --- a/R/geom-pointrange.r +++ b/R/geom-pointrange.r @@ -47,13 +47,13 @@ GeomPointrange <- ggproto("GeomPointrange", Geom, GeomLinerange$setup_data(data, params) }, - draw_panel = function(data, panel_params, coord, fatten = 4, flipped_aes = FALSE) { + draw_panel = function(data, panel_params, coord, lineend = "butt", fatten = 4, flipped_aes = FALSE) { if (is.null(data[[flipped_names(flipped_aes)$y]])) - return(GeomLinerange$draw_panel(data, panel_params, coord, flipped_aes = flipped_aes)) + return(GeomLinerange$draw_panel(data, panel_params, coord, lineend = lineend, flipped_aes = flipped_aes)) ggname("geom_pointrange", gTree(children = gList( - GeomLinerange$draw_panel(data, panel_params, coord, flipped_aes = flipped_aes), + GeomLinerange$draw_panel(data, panel_params, coord, lineend = lineend, flipped_aes = flipped_aes), GeomPoint$draw_panel(transform(data, size = size * fatten), panel_params, coord) )) ) diff --git a/R/geom-polygon.r b/R/geom-polygon.r index f44ae4d633..585b6e437d 100644 --- a/R/geom-polygon.r +++ b/R/geom-polygon.r @@ -106,7 +106,8 @@ geom_polygon <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomPolygon <- ggproto("GeomPolygon", Geom, - draw_panel = function(data, panel_params, coord, rule = "evenodd") { + draw_panel = function(data, panel_params, coord, rule = "evenodd", lineend = "butt", + linejoin = "round", linemitre = 10) { n <- nrow(data) if (n == 1) return(zeroGrob()) @@ -131,7 +132,10 @@ GeomPolygon <- ggproto("GeomPolygon", Geom, col = first_rows$colour, fill = alpha(first_rows$fill, first_rows$alpha), lwd = first_rows$size * .pt, - lty = first_rows$linetype + lty = first_rows$linetype, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre ) ) ) @@ -159,7 +163,10 @@ GeomPolygon <- ggproto("GeomPolygon", Geom, col = first_rows$colour, fill = alpha(first_rows$fill, first_rows$alpha), lwd = first_rows$size * .pt, - lty = first_rows$linetype + lty = first_rows$linetype, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre ) ) ) diff --git a/R/geom-rect.r b/R/geom-rect.r index 95cf0383e6..aa490b27e8 100644 --- a/R/geom-rect.r +++ b/R/geom-rect.r @@ -33,7 +33,7 @@ GeomRect <- ggproto("GeomRect", Geom, required_aes = c("xmin", "xmax", "ymin", "ymax"), - draw_panel = function(self, data, panel_params, coord, linejoin = "mitre") { + draw_panel = function(self, data, panel_params, coord, lineend = "butt", linejoin = "mitre") { if (!coord$is_linear()) { aesthetics <- setdiff( names(data), c("x", "y", "xmin", "xmax", "ymin", "ymax") @@ -43,7 +43,7 @@ GeomRect <- ggproto("GeomRect", Geom, poly <- rect_to_poly(row$xmin, row$xmax, row$ymin, row$ymax) aes <- new_data_frame(row[aesthetics])[rep(1,5), ] - GeomPolygon$draw_panel(cbind(poly, aes), panel_params, coord) + GeomPolygon$draw_panel(cbind(poly, aes), panel_params, coord, lineend = lineend, linejoin = linejoin) }) ggname("bar", do.call("grobTree", polys)) @@ -61,9 +61,7 @@ GeomRect <- ggproto("GeomRect", Geom, lwd = coords$size * .pt, lty = coords$linetype, linejoin = linejoin, - # `lineend` is a workaround for Windows and intentionally kept unexposed - # as an argument. (c.f. https://github.com/tidyverse/ggplot2/issues/3037#issuecomment-457504667) - lineend = if (identical(linejoin, "round")) "round" else "square" + lineend = lineend ) )) } diff --git a/R/geom-ribbon.r b/R/geom-ribbon.r index d2907e8150..8e7bd29570 100644 --- a/R/geom-ribbon.r +++ b/R/geom-ribbon.r @@ -104,7 +104,9 @@ GeomRibbon <- ggproto("GeomRibbon", Geom, data }, - draw_group = function(data, panel_params, coord, na.rm = FALSE, flipped_aes = FALSE, outline.type = "both") { + draw_group = function(data, panel_params, coord, lineend = "butt", + linejoin = "round", linemitre = 10, na.rm = FALSE, + flipped_aes = FALSE, outline.type = "both") { data <- flip_data(data, flipped_aes) if (na.rm) data <- data[stats::complete.cases(data[c("x", "ymin", "ymax")]), ] data <- data[order(data$group), ] @@ -158,7 +160,10 @@ GeomRibbon <- ggproto("GeomRibbon", Geom, fill = alpha(aes$fill, aes$alpha), col = if (is_full_outline) aes$colour else NA, lwd = if (is_full_outline) aes$size * .pt else 0, - lty = if (is_full_outline) aes$linetype else 1 + lty = if (is_full_outline) aes$linetype else 1, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre ) ) @@ -181,7 +186,11 @@ GeomRibbon <- ggproto("GeomRibbon", Geom, gp = gpar( col = aes$colour, lwd = aes$size * .pt, - lty = aes$linetype) + lty = aes$linetype, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre + ) ) ggname("geom_ribbon", grobTree(g_poly, g_lines)) diff --git a/R/geom-rug.r b/R/geom-rug.r index 2180a4286a..68e46a17f8 100644 --- a/R/geom-rug.r +++ b/R/geom-rug.r @@ -88,7 +88,8 @@ geom_rug <- function(mapping = NULL, data = NULL, GeomRug <- ggproto("GeomRug", Geom, optional_aes = c("x", "y"), - draw_panel = function(data, panel_params, coord, sides = "bl", outside = FALSE, length = unit(0.03, "npc")) { + draw_panel = function(data, panel_params, coord, lineend = "butt", sides = "bl", + outside = FALSE, length = unit(0.03, "npc")) { if (!inherits(length, "unit")) { abort("'length' must be a 'unit' object.") } @@ -108,7 +109,12 @@ GeomRug <- ggproto("GeomRug", Geom, list(min = -1 * length, max = unit(1, "npc") + length) } - gp <- gpar(col = alpha(data$colour, data$alpha), lty = data$linetype, lwd = data$size * .pt) + gp <- gpar( + col = alpha(data$colour, data$alpha), + lty = data$linetype, + lwd = data$size * .pt, + lineend = lineend + ) if (!is.null(data$x)) { if (grepl("b", sides)) { rugs$x_b <- segmentsGrob( diff --git a/R/geom-smooth.r b/R/geom-smooth.r index 05bd1a8f29..5b94f4b070 100644 --- a/R/geom-smooth.r +++ b/R/geom-smooth.r @@ -139,7 +139,8 @@ GeomSmooth <- ggproto("GeomSmooth", Geom, # ribbon won't be drawn either in that case, keeping the overall # behavior predictable and sensible. The user will realize that they # need to set `se = TRUE` to obtain the ribbon and the legend key. - draw_group = function(data, panel_params, coord, se = FALSE, flipped_aes = FALSE) { + draw_group = function(data, panel_params, coord, lineend = "butt", linejoin = "round", + linemitre = 10, se = FALSE, flipped_aes = FALSE) { ribbon <- transform(data, colour = NA) path <- transform(data, alpha = NA) @@ -149,7 +150,7 @@ GeomSmooth <- ggproto("GeomSmooth", Geom, gList( if (has_ribbon) GeomRibbon$draw_group(ribbon, panel_params, coord, flipped_aes = flipped_aes), - GeomLine$draw_panel(path, panel_params, coord) + GeomLine$draw_panel(path, panel_params, coord, lineend = lineend, linejoin = linejoin, linemitre = linemitre) ) }, diff --git a/R/geom-violin.r b/R/geom-violin.r index daad68f4d0..fe8e710389 100644 --- a/R/geom-violin.r +++ b/R/geom-violin.r @@ -120,7 +120,7 @@ GeomViolin <- ggproto("GeomViolin", Geom, params }, - extra_params = c("na.rm", "orientation"), + extra_params = c("na.rm", "orientation", "lineend", "linejoin", "linemitre"), setup_data = function(data, params) { data$flipped_aes <- params$flipped_aes diff --git a/R/geom-vline.r b/R/geom-vline.r index 3c22e0b1c9..c92d34d8c4 100644 --- a/R/geom-vline.r +++ b/R/geom-vline.r @@ -44,7 +44,7 @@ geom_vline <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomVline <- ggproto("GeomVline", Geom, - draw_panel = function(data, panel_params, coord) { + draw_panel = function(data, panel_params, coord, lineend = "butt") { ranges <- coord$backtransform_range(panel_params) data$x <- data$xintercept @@ -52,7 +52,7 @@ GeomVline <- ggproto("GeomVline", Geom, data$y <- ranges$y[1] data$yend <- ranges$y[2] - GeomSegment$draw_panel(unique(data), panel_params, coord) + GeomSegment$draw_panel(unique(data), panel_params, coord, lineend = lineend) }, default_aes = aes(colour = "black", size = 0.5, linetype = 1, alpha = NA), diff --git a/R/legend-draw.r b/R/legend-draw.r index 04266da417..ac02b97fea 100644 --- a/R/legend-draw.r +++ b/R/legend-draw.r @@ -49,7 +49,7 @@ draw_key_abline <- function(data, params, size) { col = alpha(data$colour %||% data$fill %||% "black", data$alpha), lwd = (data$size %||% 0.5) * .pt, lty = data$linetype %||% 1, - lineend = "butt" + lineend = params$lineend %||% "butt" ) ) } @@ -81,9 +81,7 @@ draw_key_polygon <- function(data, params, size) { lty = data$linetype %||% 1, lwd = lwd * .pt, linejoin = params$linejoin %||% "mitre", - # `lineend` is a workaround for Windows and intentionally kept unexposed - # as an argument. (c.f. https://github.com/tidyverse/ggplot2/issues/3037#issuecomment-457504667) - lineend = if (identical(params$linejoin, "round")) "round" else "square" + lineend = params$lineend %||% "butt" )) } @@ -105,7 +103,9 @@ draw_key_boxplot <- function(data, params, size) { col = data$colour %||% "grey20", fill = alpha(data$fill %||% "white", data$alpha), lwd = (data$size %||% 0.5) * .pt, - lty = data$linetype %||% 1 + lty = data$linetype %||% 1, + lineend = params$lineend %||% "butt", + linejoin = params$linejoin %||% "mitre" ) ) } @@ -120,7 +120,9 @@ draw_key_crossbar <- function(data, params, size) { col = data$colour %||% "grey20", fill = alpha(data$fill %||% "white", data$alpha), lwd = (data$size %||% 0.5) * .pt, - lty = data$linetype %||% 1 + lty = data$linetype %||% 1, + lineend = params$lineend %||% "butt", + linejoin = params$linejoin %||% "mitre" ) ) } @@ -141,7 +143,7 @@ draw_key_path <- function(data, params, size) { %||% data$fill %||% "black", data$alpha), lwd = (data$size %||% 0.5) * .pt, lty = data$linetype %||% 1, - lineend = "butt" + lineend = params$lineend %||% "butt" ), arrow = params$arrow ) @@ -155,7 +157,7 @@ draw_key_vpath <- function(data, params, size) { col = alpha(data$colour %||% data$fill %||% "black", data$alpha), lwd = (data$size %||% 0.5) * .pt, lty = data$linetype %||% 1, - lineend = "butt" + lineend = params$lineend %||% "butt" ), arrow = params$arrow ) @@ -168,7 +170,9 @@ draw_key_dotplot <- function(data, params, size) { pch = 21, gp = gpar( col = alpha(data$colour %||% "black", data$alpha), - fill = alpha(data$fill %||% "black", data$alpha) + fill = alpha(data$fill %||% "black", data$alpha), + lty = data$linetype %||% 1, + lineend = params$lineend %||% "butt" ) ) } @@ -227,7 +231,7 @@ draw_key_vline <- function(data, params, size) { col = alpha(data$colour %||% data$fill %||% "black", data$alpha), lwd = (data$size %||% 0.5) * .pt, lty = data$linetype %||% 1, - lineend = "butt" + lineend = params$lineend %||% "butt" ) ) } @@ -248,7 +252,8 @@ draw_key_timeseries <- function(data, params, size) { col = alpha(data$colour %||% data$fill %||% "black", data$alpha), lwd = (data$size %||% 0.5) * .pt, lty = data$linetype %||% 1, - lineend = "butt" + lineend = params$lineend %||% "butt", + linejoin = params$linejoin %||% "round" ) ) } diff --git a/tests/testthat/_snaps/aes/stat-count-width-0-5.svg b/tests/testthat/_snaps/aes/stat-count-width-0-5.svg index e983a40604..75f21c1381 100644 --- a/tests/testthat/_snaps/aes/stat-count-width-0-5.svg +++ b/tests/testthat/_snaps/aes/stat-count-width-0-5.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/aes/stat-count.svg b/tests/testthat/_snaps/aes/stat-count.svg index c3f3abbb96..a0e4f01dfd 100644 --- a/tests/testthat/_snaps/aes/stat-count.svg +++ b/tests/testthat/_snaps/aes/stat-count.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/aes/stat-identity-width-0-5.svg b/tests/testthat/_snaps/aes/stat-identity-width-0-5.svg index e669375ed3..145618e608 100644 --- a/tests/testthat/_snaps/aes/stat-identity-width-0-5.svg +++ b/tests/testthat/_snaps/aes/stat-identity-width-0-5.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/aes/stat-identity.svg b/tests/testthat/_snaps/aes/stat-identity.svg index c7707bd82c..03ab4b2621 100644 --- a/tests/testthat/_snaps/aes/stat-identity.svg +++ b/tests/testthat/_snaps/aes/stat-identity.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/coord-map/coord-map-switched-scale-position.svg b/tests/testthat/_snaps/coord-map/coord-map-switched-scale-position.svg index 44b8697d86..3d5fa0b240 100644 --- a/tests/testthat/_snaps/coord-map/coord-map-switched-scale-position.svg +++ b/tests/testthat/_snaps/coord-map/coord-map-switched-scale-position.svg @@ -36,16 +36,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/tests/testthat/_snaps/coord-map/usa-mercator.svg b/tests/testthat/_snaps/coord-map/usa-mercator.svg index de2a70c04f..c6a2038aba 100644 --- a/tests/testthat/_snaps/coord-map/usa-mercator.svg +++ b/tests/testthat/_snaps/coord-map/usa-mercator.svg @@ -36,16 +36,16 @@ - - - - - - - - - - + + + + + + + + + + diff --git a/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-has-center-hole.svg b/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-has-center-hole.svg index f92366fdaf..d5a1760e83 100644 --- a/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-has-center-hole.svg +++ b/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-has-center-hole.svg @@ -44,9 +44,9 @@ - - - + + + 1 2 0/3 diff --git a/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-no-center-hole.svg b/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-no-center-hole.svg index a920ac8382..56a632f253 100644 --- a/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-no-center-hole.svg +++ b/tests/testthat/_snaps/coord-polar/racetrack-plot-closed-and-no-center-hole.svg @@ -44,9 +44,9 @@ - - - + + + 1 2 0/3 diff --git a/tests/testthat/_snaps/coord-polar/rose-plot-with-has-equal-spacing.svg b/tests/testthat/_snaps/coord-polar/rose-plot-with-has-equal-spacing.svg index ea6d713540..c9b4539265 100644 --- a/tests/testthat/_snaps/coord-polar/rose-plot-with-has-equal-spacing.svg +++ b/tests/testthat/_snaps/coord-polar/rose-plot-with-has-equal-spacing.svg @@ -44,9 +44,9 @@ - - - + + + A B C diff --git a/tests/testthat/_snaps/draw-key/rectangle-and-dotplot-key-glyphs.svg b/tests/testthat/_snaps/draw-key/rectangle-and-dotplot-key-glyphs.svg index b777379e15..50ab636187 100644 --- a/tests/testthat/_snaps/draw-key/rectangle-and-dotplot-key-glyphs.svg +++ b/tests/testthat/_snaps/draw-key/rectangle-and-dotplot-key-glyphs.svg @@ -64,11 +64,11 @@ z - + - + - + a b c diff --git a/tests/testthat/_snaps/draw-key/time-series-and-polygon-key-glyphs.svg b/tests/testthat/_snaps/draw-key/time-series-and-polygon-key-glyphs.svg index 9f3f1b321c..e8e6e2e746 100644 --- a/tests/testthat/_snaps/draw-key/time-series-and-polygon-key-glyphs.svg +++ b/tests/testthat/_snaps/draw-key/time-series-and-polygon-key-glyphs.svg @@ -64,11 +64,11 @@ z - + - + - + a b c diff --git a/tests/testthat/_snaps/geom-boxplot/outlier-colours.svg b/tests/testthat/_snaps/geom-boxplot/outlier-colours.svg index 9fe68765e5..c3fcba0018 100644 --- a/tests/testthat/_snaps/geom-boxplot/outlier-colours.svg +++ b/tests/testthat/_snaps/geom-boxplot/outlier-colours.svg @@ -30,20 +30,20 @@ - - + + - - + + - - + + @@ -68,20 +68,20 @@ factor(cyl) - - - - + + + + - - - - + + + + - - - - + + + + 4 6 8 diff --git a/tests/testthat/_snaps/geom-dotplot/2-na-values-bin-along-y-stack-center.svg b/tests/testthat/_snaps/geom-dotplot/2-na-values-bin-along-y-stack-center.svg index 1dc6177a07..ee7f42c683 100644 --- a/tests/testthat/_snaps/geom-dotplot/2-na-values-bin-along-y-stack-center.svg +++ b/tests/testthat/_snaps/geom-dotplot/2-na-values-bin-along-y-stack-center.svg @@ -27,24 +27,24 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/2-na-values-dot-density-binning-binwidth-4.svg b/tests/testthat/_snaps/geom-dotplot/2-na-values-dot-density-binning-binwidth-4.svg index 60d7a9c242..931ddb6bd0 100644 --- a/tests/testthat/_snaps/geom-dotplot/2-na-values-dot-density-binning-binwidth-4.svg +++ b/tests/testthat/_snaps/geom-dotplot/2-na-values-dot-density-binning-binwidth-4.svg @@ -27,24 +27,24 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/3-stackgroups-bin-y-histodot.svg b/tests/testthat/_snaps/geom-dotplot/3-stackgroups-bin-y-histodot.svg index 98fb6ca6e1..b6b299a280 100644 --- a/tests/testthat/_snaps/geom-dotplot/3-stackgroups-bin-y-histodot.svg +++ b/tests/testthat/_snaps/geom-dotplot/3-stackgroups-bin-y-histodot.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -143,11 +143,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-dotplot/3-stackgroups-dot-density-with-aligned-bins.svg b/tests/testthat/_snaps/geom-dotplot/3-stackgroups-dot-density-with-aligned-bins.svg index 46d3c57a45..edc50a7707 100644 --- a/tests/testthat/_snaps/geom-dotplot/3-stackgroups-dot-density-with-aligned-bins.svg +++ b/tests/testthat/_snaps/geom-dotplot/3-stackgroups-dot-density-with-aligned-bins.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -145,11 +145,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-dotplot/3-stackgroups-histodot.svg b/tests/testthat/_snaps/geom-dotplot/3-stackgroups-histodot.svg index c5590ea87c..54ffd9c078 100644 --- a/tests/testthat/_snaps/geom-dotplot/3-stackgroups-histodot.svg +++ b/tests/testthat/_snaps/geom-dotplot/3-stackgroups-histodot.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -145,11 +145,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-dotplot/basic-dotplot-with-dot-density-binning-binwidth-4.svg b/tests/testthat/_snaps/geom-dotplot/basic-dotplot-with-dot-density-binning-binwidth-4.svg index 9cff877a24..fce6bcf822 100644 --- a/tests/testthat/_snaps/geom-dotplot/basic-dotplot-with-dot-density-binning-binwidth-4.svg +++ b/tests/testthat/_snaps/geom-dotplot/basic-dotplot-with-dot-density-binning-binwidth-4.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-center.svg b/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-center.svg index 88b364c02a..0797211f1b 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-center.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-center.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole-histodot.svg b/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole-histodot.svg index ebe5b625d3..1279678b43 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole-histodot.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole-histodot.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole.svg b/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole.svg index 195f4e2d30..ac56bcc32e 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-along-y-stack-centerwhole.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-grouping-by-x.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-grouping-by-x.svg index 5081a3f5fb..b3a2cfb7a9 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-grouping-by-x.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-grouping-by-x.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-single-x-group.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-single-x-group.svg index a4ee53e833..ff735eed28 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-single-x-group.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-continous-x-axis-single-x-group.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-dodged-coord-flip.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-dodged-coord-flip.svg index e8bea27789..6207f07469 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-dodged-coord-flip.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-dodged-coord-flip.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -153,11 +153,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-dodged.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-dodged.svg index 883307c0de..69382b9e60 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-dodged.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-dodged.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -153,11 +153,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-dodging-3-stackgroups-histodot.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-dodging-3-stackgroups-histodot.svg index b93fe6d07c..627afeac6b 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-dodging-3-stackgroups-histodot.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-dodging-3-stackgroups-histodot.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -141,9 +141,9 @@ g - + - + A B bin y, dodging, 3 stackgroups, histodot diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-across-groups.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-across-groups.svg index 96f941b067..0a2f39ef67 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-across-groups.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-across-groups.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-coord-flip.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-coord-flip.svg index 6204deb780..701a120557 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-coord-flip.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-bins-aligned-coord-flip.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-fill-and-dodge.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-fill-and-dodge.svg index e2e5527d47..fb1dd6c537 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-fill-and-dodge.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-fill-and-dodge.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -159,9 +159,9 @@ g - + - + A B bin y, three x groups, fill and dodge diff --git a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-stack-centerwhole.svg b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-stack-centerwhole.svg index 184dd556f2..a782f80460 100644 --- a/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-stack-centerwhole.svg +++ b/tests/testthat/_snaps/geom-dotplot/bin-y-three-x-groups-stack-centerwhole.svg @@ -27,96 +27,96 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/dots-stacked-closer-stackratio-5-fill-white.svg b/tests/testthat/_snaps/geom-dotplot/dots-stacked-closer-stackratio-5-fill-white.svg index 6112554a3e..49ab46365d 100644 --- a/tests/testthat/_snaps/geom-dotplot/dots-stacked-closer-stackratio-5-fill-white.svg +++ b/tests/testthat/_snaps/geom-dotplot/dots-stacked-closer-stackratio-5-fill-white.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/facets-3-groups-histodot-stackgroups.svg b/tests/testthat/_snaps/geom-dotplot/facets-3-groups-histodot-stackgroups.svg index 33a7b0c0e0..5c6d72c63b 100644 --- a/tests/testthat/_snaps/geom-dotplot/facets-3-groups-histodot-stackgroups.svg +++ b/tests/testthat/_snaps/geom-dotplot/facets-3-groups-histodot-stackgroups.svg @@ -27,36 +27,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -68,36 +68,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -109,36 +109,36 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -220,9 +220,9 @@ g - + - + A B facets, 3 groups, histodot, stackgroups diff --git a/tests/testthat/_snaps/geom-dotplot/histodot-binning-equal-bin-spacing.svg b/tests/testthat/_snaps/geom-dotplot/histodot-binning-equal-bin-spacing.svg index 2d0906d883..9b77f25400 100644 --- a/tests/testthat/_snaps/geom-dotplot/histodot-binning-equal-bin-spacing.svg +++ b/tests/testthat/_snaps/geom-dotplot/histodot-binning-equal-bin-spacing.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/larger-dots-dotsize-1-5-fill-white.svg b/tests/testthat/_snaps/geom-dotplot/larger-dots-dotsize-1-5-fill-white.svg index 46696349be..b6571b96ff 100644 --- a/tests/testthat/_snaps/geom-dotplot/larger-dots-dotsize-1-5-fill-white.svg +++ b/tests/testthat/_snaps/geom-dotplot/larger-dots-dotsize-1-5-fill-white.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-aligned.svg b/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-aligned.svg index 186529d039..87ee8f32a6 100644 --- a/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-aligned.svg +++ b/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-aligned.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -75,9 +75,9 @@ g - + - + A B multiple groups, bins aligned diff --git a/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-not-aligned.svg b/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-not-aligned.svg index 89c5c95ebc..452fb01b01 100644 --- a/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-not-aligned.svg +++ b/tests/testthat/_snaps/geom-dotplot/multiple-groups-bins-not-aligned.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -75,9 +75,9 @@ g - + - + A B multiple groups, bins not aligned diff --git a/tests/testthat/_snaps/geom-dotplot/stack-center-with-coord-flip.svg b/tests/testthat/_snaps/geom-dotplot/stack-center-with-coord-flip.svg index 13432f057f..34f05a0dc5 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-center-with-coord-flip.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-center-with-coord-flip.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-center.svg b/tests/testthat/_snaps/geom-dotplot/stack-center.svg index 9bda01b0c3..e6b4f3ea2b 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-center.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-center.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-centerwhole-with-coord-flip.svg b/tests/testthat/_snaps/geom-dotplot/stack-centerwhole-with-coord-flip.svg index 51fc5d5ecb..bd3100d471 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-centerwhole-with-coord-flip.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-centerwhole-with-coord-flip.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-centerwhole.svg b/tests/testthat/_snaps/geom-dotplot/stack-centerwhole.svg index 349635d4e9..c210702dc4 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-centerwhole.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-centerwhole.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-down-with-coord-flip.svg b/tests/testthat/_snaps/geom-dotplot/stack-down-with-coord-flip.svg index e85720ceee..3e5936aee4 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-down-with-coord-flip.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-down-with-coord-flip.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-down.svg b/tests/testthat/_snaps/geom-dotplot/stack-down.svg index b85943c371..0bc2a3283d 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-down.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-down.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-up-with-coord-flip.svg b/tests/testthat/_snaps/geom-dotplot/stack-up-with-coord-flip.svg index 14ea4f7e97..8d7bf30ccd 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-up-with-coord-flip.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-up-with-coord-flip.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/stack-up.svg b/tests/testthat/_snaps/geom-dotplot/stack-up.svg index fc804fdbee..267c45aabd 100644 --- a/tests/testthat/_snaps/geom-dotplot/stack-up.svg +++ b/tests/testthat/_snaps/geom-dotplot/stack-up.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + diff --git a/tests/testthat/_snaps/geom-dotplot/variable-linetype-and-size-specified-as-aesthetics.svg b/tests/testthat/_snaps/geom-dotplot/variable-linetype-and-size-specified-as-aesthetics.svg index 39d778d6db..dd470e13d0 100644 --- a/tests/testthat/_snaps/geom-dotplot/variable-linetype-and-size-specified-as-aesthetics.svg +++ b/tests/testthat/_snaps/geom-dotplot/variable-linetype-and-size-specified-as-aesthetics.svg @@ -27,26 +27,26 @@ - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + @@ -75,23 +75,23 @@ rep(c("a", "b"), length.out = nrow(dat)) - + - + a b rep(c(1, 2), length.out = nrow(dat)) - + - + - + - + - + 1.00 1.25 1.50 diff --git a/tests/testthat/_snaps/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg b/tests/testthat/_snaps/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg index 7626c78bb6..f76c20a281 100644 --- a/tests/testthat/_snaps/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg +++ b/tests/testthat/_snaps/geom-hline-vline-abline/cartesian-lines-intersect-mid-bars.svg @@ -27,11 +27,11 @@ - - - - - + + + + + diff --git a/tests/testthat/_snaps/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg b/tests/testthat/_snaps/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg index 3f22659a78..bdda8286d6 100644 --- a/tests/testthat/_snaps/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg +++ b/tests/testthat/_snaps/geom-hline-vline-abline/flipped-lines-intersect-mid-bars.svg @@ -27,11 +27,11 @@ - - - - - + + + + + diff --git a/tests/testthat/_snaps/geom-hline-vline-abline/polar-lines-intersect-mid-bars.svg b/tests/testthat/_snaps/geom-hline-vline-abline/polar-lines-intersect-mid-bars.svg index 9ac5fc7739..66a7e87a17 100644 --- a/tests/testthat/_snaps/geom-hline-vline-abline/polar-lines-intersect-mid-bars.svg +++ b/tests/testthat/_snaps/geom-hline-vline-abline/polar-lines-intersect-mid-bars.svg @@ -36,11 +36,11 @@ - - - - - + + + + + diff --git a/tests/testthat/_snaps/geom-polygon/basic-polygon-plot.svg b/tests/testthat/_snaps/geom-polygon/basic-polygon-plot.svg index 01e2e01c6f..e1a2dc6d8b 100644 --- a/tests/testthat/_snaps/geom-polygon/basic-polygon-plot.svg +++ b/tests/testthat/_snaps/geom-polygon/basic-polygon-plot.svg @@ -27,8 +27,8 @@ - - + + diff --git a/tests/testthat/_snaps/geom-smooth/ribbon-turned-on-in-geom-smooth.svg b/tests/testthat/_snaps/geom-smooth/ribbon-turned-on-in-geom-smooth.svg index f4e502e9be..429004d485 100644 --- a/tests/testthat/_snaps/geom-smooth/ribbon-turned-on-in-geom-smooth.svg +++ b/tests/testthat/_snaps/geom-smooth/ribbon-turned-on-in-geom-smooth.svg @@ -27,13 +27,13 @@ - - - + + + - - - + + + diff --git a/tests/testthat/_snaps/geom-violin/basic.svg b/tests/testthat/_snaps/geom-violin/basic.svg index 7b7b48e8e1..206a6b4626 100644 --- a/tests/testthat/_snaps/geom-violin/basic.svg +++ b/tests/testthat/_snaps/geom-violin/basic.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/geom-violin/continuous-x-axis-many-groups-center-should-be-at-2-0.svg b/tests/testthat/_snaps/geom-violin/continuous-x-axis-many-groups-center-should-be-at-2-0.svg index 8ae2a01166..f737690144 100644 --- a/tests/testthat/_snaps/geom-violin/continuous-x-axis-many-groups-center-should-be-at-2-0.svg +++ b/tests/testthat/_snaps/geom-violin/continuous-x-axis-many-groups-center-should-be-at-2-0.svg @@ -27,7 +27,7 @@ - + diff --git a/tests/testthat/_snaps/geom-violin/continuous-x-axis-single-group-center-should-be-at-1-0.svg b/tests/testthat/_snaps/geom-violin/continuous-x-axis-single-group-center-should-be-at-1-0.svg index be2909a5e3..f11a934abb 100644 --- a/tests/testthat/_snaps/geom-violin/continuous-x-axis-single-group-center-should-be-at-1-0.svg +++ b/tests/testthat/_snaps/geom-violin/continuous-x-axis-single-group-center-should-be-at-1-0.svg @@ -27,7 +27,7 @@ - + diff --git a/tests/testthat/_snaps/geom-violin/coord-flip.svg b/tests/testthat/_snaps/geom-violin/coord-flip.svg index de956c3d0c..434afe96c8 100644 --- a/tests/testthat/_snaps/geom-violin/coord-flip.svg +++ b/tests/testthat/_snaps/geom-violin/coord-flip.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/geom-violin/coord-polar.svg b/tests/testthat/_snaps/geom-violin/coord-polar.svg index aaf695e14d..e70e3b11f3 100644 --- a/tests/testthat/_snaps/geom-violin/coord-polar.svg +++ b/tests/testthat/_snaps/geom-violin/coord-polar.svg @@ -36,9 +36,9 @@ - - - + + + A B C diff --git a/tests/testthat/_snaps/geom-violin/dodging-and-coord-flip.svg b/tests/testthat/_snaps/geom-violin/dodging-and-coord-flip.svg index 485b5db7d2..86a328e5b5 100644 --- a/tests/testthat/_snaps/geom-violin/dodging-and-coord-flip.svg +++ b/tests/testthat/_snaps/geom-violin/dodging-and-coord-flip.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-violin/dodging.svg b/tests/testthat/_snaps/geom-violin/dodging.svg index 305199eb22..c1ccf480ce 100644 --- a/tests/testthat/_snaps/geom-violin/dodging.svg +++ b/tests/testthat/_snaps/geom-violin/dodging.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill-dodge-width-0-5.svg b/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill-dodge-width-0-5.svg index 85ac63dec4..17142781de 100644 --- a/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill-dodge-width-0-5.svg +++ b/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill-dodge-width-0-5.svg @@ -27,12 +27,12 @@ - - - - - - + + + + + + @@ -53,9 +53,9 @@ g - + - + e f grouping on x and fill, dodge width = 0.5 diff --git a/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill.svg b/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill.svg index c74994eb8c..56049d8ef6 100644 --- a/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill.svg +++ b/tests/testthat/_snaps/geom-violin/grouping-on-x-and-fill.svg @@ -27,12 +27,12 @@ - - - - - - + + + + + + @@ -53,9 +53,9 @@ g - + - + e f grouping on x and fill diff --git a/tests/testthat/_snaps/geom-violin/narrower-width-5.svg b/tests/testthat/_snaps/geom-violin/narrower-width-5.svg index 0c0af24bef..d7a23e057b 100644 --- a/tests/testthat/_snaps/geom-violin/narrower-width-5.svg +++ b/tests/testthat/_snaps/geom-violin/narrower-width-5.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/geom-violin/quantiles.svg b/tests/testthat/_snaps/geom-violin/quantiles.svg index 1c8a03cc5d..8bec1ac1a6 100644 --- a/tests/testthat/_snaps/geom-violin/quantiles.svg +++ b/tests/testthat/_snaps/geom-violin/quantiles.svg @@ -27,15 +27,15 @@ - + - + - + diff --git a/tests/testthat/_snaps/geom-violin/scale-area-to-sample-size-c-is-smaller.svg b/tests/testthat/_snaps/geom-violin/scale-area-to-sample-size-c-is-smaller.svg index a2fd1b9e99..1c0bf845b4 100644 --- a/tests/testthat/_snaps/geom-violin/scale-area-to-sample-size-c-is-smaller.svg +++ b/tests/testthat/_snaps/geom-violin/scale-area-to-sample-size-c-is-smaller.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/geom-violin/with-smaller-bandwidth-and-points.svg b/tests/testthat/_snaps/geom-violin/with-smaller-bandwidth-and-points.svg index 134a00178e..1494c6bd08 100644 --- a/tests/testthat/_snaps/geom-violin/with-smaller-bandwidth-and-points.svg +++ b/tests/testthat/_snaps/geom-violin/with-smaller-bandwidth-and-points.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/geom-violin/with-tails-and-points.svg b/tests/testthat/_snaps/geom-violin/with-tails-and-points.svg index d2b441c84d..1db22dd441 100644 --- a/tests/testthat/_snaps/geom-violin/with-tails-and-points.svg +++ b/tests/testthat/_snaps/geom-violin/with-tails-and-points.svg @@ -27,9 +27,9 @@ - - - + + + diff --git a/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left-of-legend-at-center.svg b/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left-of-legend-at-center.svg index 2e2cb20118..5f20c97519 100644 --- a/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left-of-legend-at-center.svg +++ b/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left-of-legend-at-center.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left.svg b/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left.svg index 62007709dd..ee8bca179c 100644 --- a/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left.svg +++ b/tests/testthat/_snaps/guides/legend-inside-plot-bottom-left.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/guides/legend-inside-plot-centered.svg b/tests/testthat/_snaps/guides/legend-inside-plot-centered.svg index b6edb4bece..1e2b923306 100644 --- a/tests/testthat/_snaps/guides/legend-inside-plot-centered.svg +++ b/tests/testthat/_snaps/guides/legend-inside-plot-centered.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/guides/legend-inside-plot-top-right.svg b/tests/testthat/_snaps/guides/legend-inside-plot-top-right.svg index ab25b11b5c..520196a2ab 100644 --- a/tests/testthat/_snaps/guides/legend-inside-plot-top-right.svg +++ b/tests/testthat/_snaps/guides/legend-inside-plot-top-right.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/guides/padding-in-legend-box.svg b/tests/testthat/_snaps/guides/padding-in-legend-box.svg index 1ad20d0047..22861ac8bc 100644 --- a/tests/testthat/_snaps/guides/padding-in-legend-box.svg +++ b/tests/testthat/_snaps/guides/padding-in-legend-box.svg @@ -27,9 +27,9 @@ - - - + + + @@ -54,11 +54,11 @@ x - + - + - + A B C diff --git a/tests/testthat/_snaps/position-stack/area-stacking.svg b/tests/testthat/_snaps/position-stack/area-stacking.svg index 7792c90d03..a8a8207726 100644 --- a/tests/testthat/_snaps/position-stack/area-stacking.svg +++ b/tests/testthat/_snaps/position-stack/area-stacking.svg @@ -27,10 +27,10 @@ - - - - + + + + @@ -51,9 +51,9 @@ category - + - + A B Area stacking diff --git a/tests/testthat/_snaps/scales-breaks-labels/functional-limits.svg b/tests/testthat/_snaps/scales-breaks-labels/functional-limits.svg index 0e82d87623..e0c0a6ff98 100644 --- a/tests/testthat/_snaps/scales-breaks-labels/functional-limits.svg +++ b/tests/testthat/_snaps/scales-breaks-labels/functional-limits.svg @@ -27,18 +27,18 @@ - - - - - - - - - - - - + + + + + + + + + + + + @@ -71,11 +71,11 @@ drv - + - + - + 4 f r diff --git a/tests/testthat/_snaps/stat-sum/summary-with-crossbars-manual-grouping.svg b/tests/testthat/_snaps/stat-sum/summary-with-crossbars-manual-grouping.svg index 02ab3d0f35..ef35058862 100644 --- a/tests/testthat/_snaps/stat-sum/summary-with-crossbars-manual-grouping.svg +++ b/tests/testthat/_snaps/stat-sum/summary-with-crossbars-manual-grouping.svg @@ -59,12 +59,12 @@ - - - - - - + + + + + + diff --git a/tests/testthat/_snaps/stat-sum/summary-with-crossbars-no-grouping.svg b/tests/testthat/_snaps/stat-sum/summary-with-crossbars-no-grouping.svg index dc3bc16932..ba5fd95b1b 100644 --- a/tests/testthat/_snaps/stat-sum/summary-with-crossbars-no-grouping.svg +++ b/tests/testthat/_snaps/stat-sum/summary-with-crossbars-no-grouping.svg @@ -59,12 +59,12 @@ - - - - - - + + + + + + From 0a6927fe89b3d9e25722cc50b35b38044f06029a Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Fri, 12 Nov 2021 08:17:55 +0100 Subject: [PATCH 18/32] Make weight a recognised aesthetic (#4666) --- NEWS.md | 3 +++ R/stat-bin2d.r | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index e8b0c809ff..b300aa24e9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* `stat_bin_2d()` now correctly recognises the `weight` aesthetic + (@thomasp85, #4646) + * All geoms now have consistent exposure of linejoin and lineend parameters, and the guide keys will now respect these settings (@thomasp85, #4653) diff --git a/R/stat-bin2d.r b/R/stat-bin2d.r index dd1ed1b77d..bf3fd73328 100644 --- a/R/stat-bin2d.r +++ b/R/stat-bin2d.r @@ -50,7 +50,7 @@ stat_bin2d <- stat_bin_2d #' @usage NULL #' @export StatBin2d <- ggproto("StatBin2d", Stat, - default_aes = aes(fill = after_stat(count)), + default_aes = aes(weight = 1, fill = after_stat(count)), required_aes = c("x", "y"), compute_group = function(data, scales, binwidth = NULL, bins = 30, From 4d2333a941d37c91c92ce816fc31120ab28f8f62 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Fri, 12 Nov 2021 08:21:26 +0100 Subject: [PATCH 19/32] treat stroke == NA as 0 (#4667) --- NEWS.md | 3 +++ R/geom-point.r | 4 +++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index b300aa24e9..5163888679 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Setting `stroke` to `NA` in `geom_point()` will no longer impair the sizing of + the points (@thomasp85, #4624) + * `stat_bin_2d()` now correctly recognises the `weight` aesthetic (@thomasp85, #4646) diff --git a/R/geom-point.r b/R/geom-point.r index db74504a50..2981a909dc 100644 --- a/R/geom-point.r +++ b/R/geom-point.r @@ -122,6 +122,8 @@ GeomPoint <- ggproto("GeomPoint", Geom, } coords <- coord$transform(data, panel_params) + stroke_size <- coords$stroke + stroke_size[is.na(stroke_size)] <- 0 ggname("geom_point", pointsGrob( coords$x, coords$y, @@ -130,7 +132,7 @@ GeomPoint <- ggproto("GeomPoint", Geom, col = alpha(coords$colour, coords$alpha), fill = alpha(coords$fill, coords$alpha), # Stroke is added around the outside of the point - fontsize = coords$size * .pt + coords$stroke * .stroke / 2, + fontsize = coords$size * .pt + stroke_size * .stroke / 2, lwd = coords$stroke * .stroke / 2 ) ) From 073c9a082f691d6b9a9f1322f026d2dda7ecb061 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Tue, 16 Nov 2021 21:00:37 +0100 Subject: [PATCH 20/32] Convert size = NA to 0 before rendering (#4672) --- NEWS.md | 3 +++ R/guide-legend.r | 5 +++++ tests/testthat/test-guides.R | 11 +++++++++++ 3 files changed, 19 insertions(+) diff --git a/NEWS.md b/NEWS.md index 5163888679..7d306c43c1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Setting `size = NA` will no longer cause `guide_legend()` to error + (@thomasp85, #4559) + * Setting `stroke` to `NA` in `geom_point()` will no longer impair the sizing of the points (@thomasp85, #4624) diff --git a/R/guide-legend.r b/R/guide-legend.r index 7ecb2a0802..b6cb608082 100644 --- a/R/guide-legend.r +++ b/R/guide-legend.r @@ -278,6 +278,10 @@ guide_geom.legend <- function(guide, layers, default_mapping) { # override.aes in guide_legend manually changes the geom data <- modify_list(data, guide$override.aes) + if (!is.null(data$size)) { + data$size[is.na(data$size)] <- 0 + } + list( draw_key = layer$geom$draw_key, data = data, @@ -383,6 +387,7 @@ guide_gengrob.legend <- function(guide, theme) { ) key_size_mat <- do.call("cbind", lapply(guide$geoms, function(g) g$data$size / 10)) + if (nrow(key_size_mat) == 0 || ncol(key_size_mat) == 0) { key_size_mat <- matrix(0, ncol = 1, nrow = nbreak) } diff --git a/tests/testthat/test-guides.R b/tests/testthat/test-guides.R index c65f649794..7247cac8b1 100644 --- a/tests/testthat/test-guides.R +++ b/tests/testthat/test-guides.R @@ -182,6 +182,17 @@ test_that("guide merging for guide_legend() works as expected", { expect_equal(repeated_identical_labels[[1]]$key$.label, c("label1", "label1", "label2")) }) +test_that("size = NA doesn't throw rendering errors", { + df = data.frame( + x = c(1, 2), + group = c("a","b") + ) + p <- ggplot(df, aes(x = x, y = 0, colour = group)) + + geom_point(size = NA, na.rm = TRUE) + + expect_silent(plot(p)) +}) + # Visual tests ------------------------------------------------------------ test_that("axis guides are drawn correctly", { From 65d3bfc21b279a799a5450272664625b01c8778f Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Tue, 16 Nov 2021 21:04:58 +0100 Subject: [PATCH 21/32] follow tidyverse recycling rules for aesthetics (#4670) --- NEWS.md | 3 +++ R/geom-.r | 2 +- R/layer.r | 3 ++- tests/testthat/test-aes-setting.r | 11 +++++++++++ 4 files changed, 17 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 7d306c43c1..f7a93a88e4 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Aesthetics of length 1 are now recycled to 0 if the length of the data is 0 + (@thomasp85, #4588) + * Setting `size = NA` will no longer cause `guide_legend()` to error (@thomasp85, #4559) diff --git a/R/geom-.r b/R/geom-.r index e513769c03..8265d6cd4c 100644 --- a/R/geom-.r +++ b/R/geom-.r @@ -208,7 +208,7 @@ NULL .stroke <- 96 / 25.4 check_aesthetics <- function(x, n) { - ns <- vapply(x, length, numeric(1)) + ns <- vapply(x, length, integer(1)) good <- ns == 1L | ns == n if (all(good)) { diff --git a/R/layer.r b/R/layer.r index 197d32549d..dcb66f92bf 100644 --- a/R/layer.r +++ b/R/layer.r @@ -264,7 +264,8 @@ Layer <- ggproto("Layer", NULL, if (length(evaled) == 0) { n <- 0 } else { - n <- max(vapply(evaled, length, integer(1))) + aes_n <- vapply(evaled, length, integer(1)) + n <- if (min(aes_n) == 0) 0L else max(aes_n) } } check_aesthetics(evaled, n) diff --git a/tests/testthat/test-aes-setting.r b/tests/testthat/test-aes-setting.r index baa6a12077..4c3e055ea8 100644 --- a/tests/testthat/test-aes-setting.r +++ b/tests/testthat/test-aes-setting.r @@ -13,6 +13,17 @@ test_that("aesthetic parameters match length of data", { set_colours(rep("red", 5)) }) +test_that("Length 1 aesthetics are recycled to 0", { + p <- ggplot(data.frame(x = numeric(), y = numeric())) + + geom_point(aes(x, y, colour = "red")) + + expect_silent(plot(p)) + + data <- layer_data(p) + + expect_equal(nrow(data), 0) +}) + test_that("legend filters out aesthetics not of length 1", { df <- data_frame(x = 1:5, y = 1:5) p <- ggplot(df, aes(x, y, colour = factor(x))) + From 199eb90981f6331e51f373bae2ba2b8269128091 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Tue, 16 Nov 2021 21:08:31 +0100 Subject: [PATCH 22/32] check if axis is present before adding padding to facet_grid (#4669) --- NEWS.md | 3 +++ R/facet-grid-.r | 20 ++++++++++++-------- tests/testthat/test-facet-strips.r | 26 ++++++++++++++++++++++++++ 3 files changed, 41 insertions(+), 8 deletions(-) diff --git a/NEWS.md b/NEWS.md index f7a93a88e4..9a8a8fc713 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Strip padding in `facet_grid()` is now only in effect if `strip.placement = "outside"` + _and_ an axis is present between the strip and the panel (@thomasp85, #4610) + * Aesthetics of length 1 are now recycled to 0 if the length of the data is 0 (@thomasp85, #4588) diff --git a/R/facet-grid-.r b/R/facet-grid-.r index c5ec246a70..a31ba9bb2f 100644 --- a/R/facet-grid-.r +++ b/R/facet-grid-.r @@ -356,10 +356,14 @@ FacetGrid <- ggproto("FacetGrid", Facet, theme$panel.spacing.y %||% theme$panel.spacing) # Add axes - panel_table <- gtable_add_rows(panel_table, max_height(axes$x$top), 0) - panel_table <- gtable_add_rows(panel_table, max_height(axes$x$bottom), -1) - panel_table <- gtable_add_cols(panel_table, max_width(axes$y$left), 0) - panel_table <- gtable_add_cols(panel_table, max_width(axes$y$right), -1) + axis_height_top <- max_height(axes$x$top) + axis_height_bottom <- max_height(axes$x$bottom) + axis_width_left <- max_width(axes$y$left) + axis_width_right <- max_width(axes$y$right) + panel_table <- gtable_add_rows(panel_table, axis_height_top, 0) + panel_table <- gtable_add_rows(panel_table, axis_height_bottom, -1) + panel_table <- gtable_add_cols(panel_table, axis_width_left, 0) + panel_table <- gtable_add_cols(panel_table, axis_width_right, -1) panel_pos_col <- panel_cols(panel_table) panel_pos_rows <- panel_rows(panel_table) @@ -377,7 +381,7 @@ FacetGrid <- ggproto("FacetGrid", Facet, panel_pos_col <- panel_cols(panel_table) if (switch_x) { if (!is.null(strips$x$bottom)) { - if (inside_x) { + if (inside_x || as.numeric(axis_height_bottom) == 0) { panel_table <- gtable_add_rows(panel_table, max_height(strips$x$bottom), -2) panel_table <- gtable_add_grob(panel_table, strips$x$bottom, -2, panel_pos_col$l, clip = "on", name = paste0("strip-b-", seq_along(strips$x$bottom)), z = 2) } else { @@ -388,7 +392,7 @@ FacetGrid <- ggproto("FacetGrid", Facet, } } else { if (!is.null(strips$x$top)) { - if (inside_x) { + if (inside_x || as.numeric(axis_height_top) == 0) { panel_table <- gtable_add_rows(panel_table, max_height(strips$x$top), 1) panel_table <- gtable_add_grob(panel_table, strips$x$top, 2, panel_pos_col$l, clip = "on", name = paste0("strip-t-", seq_along(strips$x$top)), z = 2) } else { @@ -401,7 +405,7 @@ FacetGrid <- ggproto("FacetGrid", Facet, panel_pos_rows <- panel_rows(panel_table) if (switch_y) { if (!is.null(strips$y$left)) { - if (inside_y) { + if (inside_y || as.numeric(axis_width_left) == 0) { panel_table <- gtable_add_cols(panel_table, max_width(strips$y$left), 1) panel_table <- gtable_add_grob(panel_table, strips$y$left, panel_pos_rows$t, 2, clip = "on", name = paste0("strip-l-", seq_along(strips$y$left)), z = 2) } else { @@ -412,7 +416,7 @@ FacetGrid <- ggproto("FacetGrid", Facet, } } else { if (!is.null(strips$y$right)) { - if (inside_y) { + if (inside_y || as.numeric(axis_width_right) == 0) { panel_table <- gtable_add_cols(panel_table, max_width(strips$y$right), -2) panel_table <- gtable_add_grob(panel_table, strips$y$right, panel_pos_rows$t, -2, clip = "on", name = paste0("strip-r-", seq_along(strips$y$right)), z = 2) } else { diff --git a/tests/testthat/test-facet-strips.r b/tests/testthat/test-facet-strips.r index 4536eb73d7..269fea8e62 100644 --- a/tests/testthat/test-facet-strips.r +++ b/tests/testthat/test-facet-strips.r @@ -131,6 +131,32 @@ test_that("strips can be removed", { expect_true(all(sapply(strip_grobs, inherits, 'zeroGrob'))) }) +test_that("strips can be removed", { + dat <- data_frame(a = rep(LETTERS[1:10], 10), x = rnorm(100), y = rnorm(100)) + g <- ggplot(dat, aes(x = x, y = y)) + + geom_point() + + facet_wrap(~a) + + theme(strip.background = element_blank(), strip.text = element_blank()) + g_grobs <- ggplotGrob(g) + strip_grobs <- g_grobs$grobs[grepl('strip-', g_grobs$layout$name)] + expect_true(all(sapply(strip_grobs, inherits, 'zeroGrob'))) +}) + +test_that("padding is only added if axis is present", { + p <- ggplot(data = mpg, aes(x = displ, y = hwy)) + + facet_grid(. ~ drv) + + theme( + strip.placement = "outside", + strip.switch.pad.grid = unit(10, "mm") + ) + pg <- ggplotGrob(p) + expect_equal(length(pg$heights), 13) + + pg <- ggplotGrob(p + scale_x_continuous(position = "top")) + expect_equal(length(pg$heights), 14) + expect_equal(as.character(pg$heights[7]), "1cm") +}) + test_that("y strip labels are rotated when strips are switched", { switched <- p + facet_grid(am ~ cyl, switch = "both") From a1b7054700f68898ecde220f373d685e1eb15f38 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Wed, 24 Nov 2021 09:21:09 +0100 Subject: [PATCH 23/32] Check if transformed limits are valid before assigning them (#4676) --- NEWS.md | 3 +++ R/scale-.r | 5 +++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/NEWS.md b/NEWS.md index 9a8a8fc713..7fe401e086 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Binning scales are now more resilient to calculated limits that ends up being + `NaN` after transformations (@thomasp85, #4510) + * Strip padding in `facet_grid()` is now only in effect if `strip.placement = "outside"` _and_ an axis is present between the strip and the panel (@thomasp85, #4610) diff --git a/R/scale-.r b/R/scale-.r index 6c289e63b7..91c35cd35f 100644 --- a/R/scale-.r +++ b/R/scale-.r @@ -1083,11 +1083,12 @@ ScaleBinned <- ggproto("ScaleBinned", Scale, new_limits[1] <- breaks[1] breaks <- breaks[-1] } - limits <- new_limits } else { bin_size <- max(breaks[1] - limits[1], limits[2] - breaks[1]) - limits <- c(breaks[1] - bin_size, breaks[1] + bin_size) + new_limits <- c(breaks[1] - bin_size, breaks[1] + bin_size) } + new_limits_trans <- suppressWarnings(self$trans$transform(new_limits)) + limits[is.finite(new_limits_trans)] <- new_limits[is.finite(new_limits_trans)] self$limits <- self$trans$transform(limits) } } else if (is.function(self$breaks)) { From 13f9e566c813c3f75af70506d12a2243e1980aa3 Mon Sep 17 00:00:00 2001 From: Jan Gleixner Date: Wed, 24 Nov 2021 09:22:56 +0100 Subject: [PATCH 24/32] docs: turn reference to arrow into link (#4675) --- R/geom-segment.r | 2 +- man/geom_segment.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/geom-segment.r b/R/geom-segment.r index 01965739bd..fe922e5093 100644 --- a/R/geom-segment.r +++ b/R/geom-segment.r @@ -11,7 +11,7 @@ #' @eval rd_aesthetics("geom", "segment") #' @inheritParams layer #' @inheritParams geom_point -#' @param arrow specification for arrow heads, as created by arrow(). +#' @param arrow specification for arrow heads, as created by [grid::arrow()]. #' @param arrow.fill fill colour to use for the arrow head (if closed). `NULL` #' means use `colour` aesthetic. #' @param lineend Line end style (round, butt, square). diff --git a/man/geom_segment.Rd b/man/geom_segment.Rd index 5cfa8057b5..563f61a0f9 100644 --- a/man/geom_segment.Rd +++ b/man/geom_segment.Rd @@ -69,7 +69,7 @@ often aesthetics, used to set an aesthetic to a fixed value, like \code{colour = "red"} or \code{size = 3}. They may also be parameters to the paired geom/stat.} -\item{arrow}{specification for arrow heads, as created by arrow().} +\item{arrow}{specification for arrow heads, as created by \code{\link[grid:arrow]{grid::arrow()}}.} \item{arrow.fill}{fill colour to use for the arrow head (if closed). \code{NULL} means use \code{colour} aesthetic.} From 391a1647df0168dbca0e8c58959229fa62e4dc5c Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Wed, 24 Nov 2021 09:25:48 +0100 Subject: [PATCH 25/32] Remove filename from the call to custom devices if file is present in the formals (#4674) --- NEWS.md | 3 +++ R/save.r | 1 + 2 files changed, 4 insertions(+) diff --git a/NEWS.md b/NEWS.md index 7fe401e086..2b9f22fb99 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Better compatibility of custom device functions in `ggsave()` + (@thomasp85, #4539) + * Binning scales are now more resilient to calculated limits that ends up being `NaN` after transformations (@thomasp85, #4510) diff --git a/R/save.r b/R/save.r index 8238f893c6..0a5738f22f 100644 --- a/R/save.r +++ b/R/save.r @@ -162,6 +162,7 @@ plot_dev <- function(device, filename = NULL, dpi = 300) { call_args <- list() if ("file" %in% names(args)) { call_args$file <- filename + call_args["filename"] <- list(NULL) } if ("res" %in% names(args)) { call_args$res <- dpi From bd50a5515516fc18ed9a6f13d074ba6016b34721 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Wed, 24 Nov 2021 09:56:00 +0100 Subject: [PATCH 26/32] Make sure axes are added correctly to facet_wrap in all circumstances (#4673) --- NEWS.md | 3 + R/facet-wrap.r | 84 ++- ...sitioned-correctly-in-non-table-layout.svg | 504 ++++++++++++++++++ tests/testthat/test-facet-layout.r | 8 + 4 files changed, 577 insertions(+), 22 deletions(-) create mode 100644 tests/testthat/_snaps/facet-layout/axes-are-positioned-correctly-in-non-table-layout.svg diff --git a/NEWS.md b/NEWS.md index 2b9f22fb99..f8fc338eda 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Axes are now added correctly in `facet_wrap()` when `as.table = FALSE` + (@thomasp85, #4553) + * Better compatibility of custom device functions in `ggsave()` (@thomasp85, #4539) diff --git a/R/facet-wrap.r b/R/facet-wrap.r index 47bf1f471f..e6f34cd7af 100644 --- a/R/facet-wrap.r +++ b/R/facet-wrap.r @@ -313,30 +313,70 @@ FacetWrap <- ggproto("FacetWrap", Facet, ) # Add back missing axes if (any(empties)) { - first_row <- which(apply(empties, 1, any))[1] - 1 - first_col <- which(apply(empties, 2, any))[1] - 1 - row_panels <- which(layout$ROW == first_row & layout$COL > first_col) - row_pos <- convertInd(layout$ROW[row_panels], layout$COL[row_panels], nrow) - row_axes <- axes$x$bottom[layout$SCALE_X[row_panels]] - col_panels <- which(layout$ROW > first_row & layout$COL == first_col) - col_pos <- convertInd(layout$ROW[col_panels], layout$COL[col_panels], nrow) - col_axes <- axes$y$right[layout$SCALE_Y[col_panels]] + row_ind <- row(empties) + col_ind <- col(empties) inside <- (theme$strip.placement %||% "inside") == "inside" - if (params$strip.position == "bottom" && - !inside && - any(!vapply(row_axes, is.zero, logical(1))) && - !params$free$x) { - warn("Suppressing axis rendering when strip.position = 'bottom' and strip.placement == 'outside'") - } else { - axis_mat_x_bottom[row_pos] <- row_axes + empty_bottom <- apply(empties, 2, function(x) c(diff(x) == 1, FALSE)) + if (any(empty_bottom)) { + pos <- which(empty_bottom) + panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos]) + # Substitute with vctrs::vec_match(panel_loc, layout[, c("ROW", "COL")]) + # Once we switch to vctrs wholesale + panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index + x_axes <- axes$x$bottom[layout$SCALE_X[panels]] + if (params$strip.position == "bottom" && + !inside && + any(!vapply(x_axes, is.zero, logical(1))) && + !params$free$x) { + warn("Suppressing axis rendering when strip.position = 'bottom' and strip.placement == 'outside'") + } else { + axis_mat_x_bottom[pos] <- x_axes + } } - if (params$strip.position == "right" && - !inside && - any(!vapply(col_axes, is.zero, logical(1))) && - !params$free$y) { - warn("Suppressing axis rendering when strip.position = 'right' and strip.placement == 'outside'") - } else { - axis_mat_y_right[col_pos] <- col_axes + empty_top <- apply(empties, 2, function(x) c(FALSE, diff(x) == -1)) + if (any(empty_top)) { + pos <- which(empty_top) + panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos]) + panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index + x_axes <- axes$x$top[layout$SCALE_X[panels]] + if (params$strip.position == "top" && + !inside && + any(!vapply(x_axes, is.zero, logical(1))) && + !params$free$x) { + warn("Suppressing axis rendering when strip.position = 'top' and strip.placement == 'outside'") + } else { + axis_mat_x_top[pos] <- x_axes + } + } + empty_right <- t(apply(empties, 1, function(x) c(diff(x) == 1, FALSE))) + if (any(empty_right)) { + pos <- which(empty_right) + panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos]) + panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index + y_axes <- axes$y$right[layout$SCALE_Y[panels]] + if (params$strip.position == "right" && + !inside && + any(!vapply(y_axes, is.zero, logical(1))) && + !params$free$y) { + warn("Suppressing axis rendering when strip.position = 'right' and strip.placement == 'outside'") + } else { + axis_mat_y_right[pos] <- y_axes + } + } + empty_left <- t(apply(empties, 1, function(x) c(FALSE, diff(x) == -1))) + if (any(empty_left)) { + pos <- which(empty_left) + panel_loc <- data_frame(ROW = row_ind[pos], COL = col_ind[pos]) + panels <- merge(panel_loc, cbind(layout, .index = seq_len(nrow(layout))))$.index + y_axes <- axes$y$left[layout$SCALE_Y[panels]] + if (params$strip.position == "left" && + !inside && + any(!vapply(y_axes, is.zero, logical(1))) && + !params$free$y) { + warn("Suppressing axis rendering when strip.position = 'left' and strip.placement == 'outside'") + } else { + axis_mat_y_left[pos] <- y_axes + } } } panel_table <- weave_tables_row(panel_table, axis_mat_x_top, -1, axis_height_top, "axis-t", 3) diff --git a/tests/testthat/_snaps/facet-layout/axes-are-positioned-correctly-in-non-table-layout.svg b/tests/testthat/_snaps/facet-layout/axes-are-positioned-correctly-in-non-table-layout.svg new file mode 100644 index 0000000000..675d65dd25 --- /dev/null +++ b/tests/testthat/_snaps/facet-layout/axes-are-positioned-correctly-in-non-table-layout.svg @@ -0,0 +1,504 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +subcompact + + + + + + + + + + +midsize + + + + + + + + + + + + + + + + + + + +pickup + + + + + + + + + + +compact + + + + + + + + + + +suv + + + + + + + + + + +minivan + + + + + + + + + + +2seater + + + + + + + + +2 +3 +4 +5 +6 +7 + + + + + + +2 +3 +4 +5 +6 +7 + + + + + + +2 +3 +4 +5 +6 +7 +20 +30 +40 + + + +20 +30 +40 + + + +20 +30 +40 + + + +displ +hwy +Axes are positioned correctly in non-table layout + + diff --git a/tests/testthat/test-facet-layout.r b/tests/testthat/test-facet-layout.r index b975135557..bf99bbec00 100644 --- a/tests/testthat/test-facet-layout.r +++ b/tests/testthat/test-facet-layout.r @@ -80,6 +80,14 @@ test_that("wrap: as.table reverses rows", { expect_equal(two$ROW, c(1, 1)) }) +test_that("wrap: as.table = FALSE gets axes", { + p <- ggplot(mpg, aes(displ, hwy)) + + geom_point() + + scale_y_continuous(position = "left") + + facet_wrap(vars(class), dir = "v", as.table = FALSE) + expect_doppelganger("Axes are positioned correctly in non-table layout", p) +}) + test_that("grid: as.table reverses rows", { one <- panel_layout(facet_grid(a~., as.table = FALSE), list(a)) expect_equal(as.character(one$a), c("2", "1")) From b029aa5a7e0d9ce863e5c2683ee3464bfb24d5c6 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 6 Dec 2021 10:31:15 +0100 Subject: [PATCH 27/32] Check for range == NULL - happens if no data has been added to plot (#4682) --- NEWS.md | 3 +++ R/axis-secondary.R | 6 ++++++ 2 files changed, 9 insertions(+) diff --git a/NEWS.md b/NEWS.md index f8fc338eda..708ec55d62 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* Fixed a bug throwing errors when trying to render an empty plot with secondary + axes (@thomasp85, #4509) + * Axes are now added correctly in `facet_wrap()` when `as.table = FALSE` (@thomasp85, #4553) diff --git a/R/axis-secondary.R b/R/axis-secondary.R index 28cd8ece2d..e25e21fca9 100644 --- a/R/axis-secondary.R +++ b/R/axis-secondary.R @@ -174,6 +174,12 @@ AxisSecondary <- ggproto("AxisSecondary", NULL, mono_test = function(self, scale){ range <- scale$range$range + + # Check if plot is empty + if (is.null(range)) { + return() + } + along_range <- seq(range[1], range[2], length.out = self$detail) old_range <- scale$trans$inverse(along_range) From 4e3f0e1b25ad0efe68f8304576b543caadd156d1 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 6 Dec 2021 10:40:26 +0100 Subject: [PATCH 28/32] Pass on binwidth and height to geom (#4671) --- NEWS.md | 5 + R/geom-hex.r | 36 +++- R/hexbin.R | 2 + .../hex-bin-plot-in-polar-coordinates.svg | 183 ++++++++++++++++++ .../hex-bin-plot-with-sqrt-transformed-y.svg | 181 +++++++++++++++++ ...e-hex-bin-with-width-and-height-of-0-1.svg | 64 ++++++ tests/testthat/test-geom-hex.R | 23 ++- 7 files changed, 488 insertions(+), 6 deletions(-) create mode 100644 tests/testthat/_snaps/geom-hex/hex-bin-plot-in-polar-coordinates.svg create mode 100644 tests/testthat/_snaps/geom-hex/hex-bin-plot-with-sqrt-transformed-y.svg create mode 100644 tests/testthat/_snaps/geom-hex/single-hex-bin-with-width-and-height-of-0-1.svg diff --git a/NEWS.md b/NEWS.md index 708ec55d62..61372a1a25 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,10 @@ # ggplot2 (development version) +* `geom_hex()` will now use the binwidth from `stat_bin_hex()` if present, + instead of deriving it (@thomasp85, #4580) + +* `geom_hex()` now works on non-linear coordinate systems (@thomasp85) + * Fixed a bug throwing errors when trying to render an empty plot with secondary axes (@thomasp85, #4509) diff --git a/R/geom-hex.r b/R/geom-hex.r index 2e18b221e9..e28e1cbe74 100644 --- a/R/geom-hex.r +++ b/R/geom-hex.r @@ -56,12 +56,36 @@ geom_hex <- function(mapping = NULL, data = NULL, GeomHex <- ggproto("GeomHex", Geom, draw_group = function(data, panel_params, coord, lineend = "butt", linejoin = "mitre", linemitre = 10) { - if (!inherits(coord, "CoordCartesian")) { - abort("geom_hex() only works with Cartesian coordinates") + if (empty(data)) { + return(zeroGrob()) } + # Get hex sizes + if (!is.null(data$width)) { + dx <- data$width[1] / 2 + } else { + dx <- resolution(data$x, FALSE) + } + # Adjust for difference in width and height of regular hexagon. 1.15 adjusts + # for the effect of the overlapping range in y-direction on the resolution + # calculation + if (!is.null(data$height)) { + dy <- data$height[1] / sqrt(3) / 2 + } else { + dy <- resolution(data$y, FALSE) / sqrt(3) / 2 * 1.15 + } + + hexC <- hexbin::hexcoords(dx, dy, n = 1) + + n <- nrow(data) + + data <- data[rep(seq_len(n), each = 6), ] + data$x <- rep.int(hexC$x, n) + data$x + data$y <- rep.int(hexC$y, n) + data$y + coords <- coord$transform(data, panel_params) - ggname("geom_hex", hexGrob( + + ggname("geom_hex", polygonGrob( coords$x, coords$y, gp = gpar( col = coords$colour, @@ -71,7 +95,9 @@ GeomHex <- ggproto("GeomHex", Geom, lineend = lineend, linejoin = linejoin, linemitre = linemitre - ) + ), + default.units = "native", + id.lengths = rep.int(6, n) )) }, @@ -97,6 +123,8 @@ GeomHex <- ggproto("GeomHex", Geom, # @param size vector of hex sizes # @param gp graphical parameters # @keyword internal +# +# THIS IS NO LONGER USED BUT LEFT IF CODE SOMEWHERE ELSE RELIES ON IT hexGrob <- function(x, y, size = rep(1, length(x)), gp = gpar()) { if (length(y) != length(x)) abort("`x` and `y` must have the same length") diff --git a/R/hexbin.R b/R/hexbin.R index 6d6e38e5fd..296f8f2cce 100644 --- a/R/hexbin.R +++ b/R/hexbin.R @@ -36,6 +36,8 @@ hexBinSummarise <- function(x, y, z, binwidth, fun = mean, fun.args = list(), dr # Convert to data frame out <- new_data_frame(hexbin::hcell2xy(hb)) out$value <- as.vector(value) + out$width <- binwidth[1] + out$height <- binwidth[2] if (drop) out <- stats::na.omit(out) out diff --git a/tests/testthat/_snaps/geom-hex/hex-bin-plot-in-polar-coordinates.svg b/tests/testthat/_snaps/geom-hex/hex-bin-plot-in-polar-coordinates.svg new file mode 100644 index 0000000000..34bc427bd8 --- /dev/null +++ b/tests/testthat/_snaps/geom-hex/hex-bin-plot-in-polar-coordinates.svg @@ -0,0 +1,183 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +2 +3 +4 +5 +6 + + + +20 +30 +40 + + + +displ +hwy + + +2.5 +5.0 +7.5 +10.0 +count + + + + + + + + +hex bin plot in polar coordinates + + diff --git a/tests/testthat/_snaps/geom-hex/hex-bin-plot-with-sqrt-transformed-y.svg b/tests/testthat/_snaps/geom-hex/hex-bin-plot-with-sqrt-transformed-y.svg new file mode 100644 index 0000000000..82486696e1 --- /dev/null +++ b/tests/testthat/_snaps/geom-hex/hex-bin-plot-with-sqrt-transformed-y.svg @@ -0,0 +1,181 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +20 +30 +40 + + + + + + + + + +2 +3 +4 +5 +6 +7 +displ +hwy + + +2.5 +5.0 +7.5 +10.0 +count + + + + + + + + +hex bin plot with sqrt-transformed y + + diff --git a/tests/testthat/_snaps/geom-hex/single-hex-bin-with-width-and-height-of-0-1.svg b/tests/testthat/_snaps/geom-hex/single-hex-bin-with-width-and-height-of-0-1.svg new file mode 100644 index 0000000000..ec51b6ab15 --- /dev/null +++ b/tests/testthat/_snaps/geom-hex/single-hex-bin-with-width-and-height-of-0-1.svg @@ -0,0 +1,64 @@ + + + + + + + + + + + + + + + + + + + + + + + + + +-1.0 +-0.5 +0.0 +0.5 +1.0 + + + + + + + + + + +-1.0 +-0.5 +0.0 +0.5 +1.0 +x +y + + +1 +count + + +single hex bin with width and height of 0.1 + + diff --git a/tests/testthat/test-geom-hex.R b/tests/testthat/test-geom-hex.R index 3cffeb8a66..82465e2183 100644 --- a/tests/testthat/test-geom-hex.R +++ b/tests/testthat/test-geom-hex.R @@ -15,6 +15,25 @@ test_that("size and linetype are applied", { geom_hex(color = "red", size = 4, linetype = 2) gpar <- layer_grob(plot)[[1]]$children[[1]]$gp - expect_equal(gpar$lwd, c(4, 4) * .pt, tolerance = 1e-7) - expect_equal(gpar$lty, c(2, 2), tolerance = 1e-7) + expect_equal(gpar$lwd, rep(4, 12) * .pt, tolerance = 1e-7) + expect_equal(gpar$lty, rep(2, 12), tolerance = 1e-7) +}) + +test_that("bin size are picked up from stat", { + expect_doppelganger("single hex bin with width and height of 0.1", + ggplot(data.frame(x = 0, y = 0)) + + geom_hex(aes(x = x, y = y), binwidth = c(0.1, 0.1)) + + coord_cartesian(xlim = c(-1, 1), ylim = c(-1, 1)) + ) +}) + +test_that("geom_hex works in non-linear coordinate systems", { + p <- ggplot(mpg, aes(displ, hwy)) + geom_hex() + + expect_doppelganger("hex bin plot with sqrt-transformed y", + p + coord_trans(y = "sqrt") + ) + expect_doppelganger("hex bin plot in polar coordinates", + p + coord_polar() + ) }) From 74e11033607d047a10c856e71b13593cf0762387 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Mon, 6 Dec 2021 10:41:22 +0100 Subject: [PATCH 29/32] Add non_missing_aes to geom_tile (#4683) --- NEWS.md | 3 +++ R/geom-tile.r | 5 +++++ 2 files changed, 8 insertions(+) diff --git a/NEWS.md b/NEWS.md index 61372a1a25..54453eba92 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,8 @@ # ggplot2 (development version) +* `geom_tile()` now correctly recognises missing data in `xmin`, `xmax`, `ymin`, + and `ymax` (@thomasp85 and @sigmapi, #4495) + * `geom_hex()` will now use the binwidth from `stat_bin_hex()` if present, instead of deriving it (@thomasp85, #4580) diff --git a/R/geom-tile.r b/R/geom-tile.r index 41a5b9109c..f1d6bc3bc7 100644 --- a/R/geom-tile.r +++ b/R/geom-tile.r @@ -113,5 +113,10 @@ GeomTile <- ggproto("GeomTile", GeomRect, required_aes = c("x", "y"), + # These aes columns are created by setup_data(). They need to be listed here so + # that GeomRect$handle_na() properly removes any bars that fall outside the defined + # limits, not just those for which x and y are outside the limits + non_missing_aes = c("xmin", "xmax", "ymin", "ymax"), + draw_key = draw_key_polygon ) From c89c265a57fd71f8a0288ce81037296aadc0a012 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Thu, 9 Dec 2021 08:19:38 +0100 Subject: [PATCH 30/32] Ensure output is numeric even if ifelse clause is NA (#4692) --- NEWS.md | 2 ++ R/position-stack.r | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NEWS.md b/NEWS.md index 54453eba92..6579c613b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,5 +1,7 @@ # ggplot2 (development version) +* `position_stack()` now works fully with `geom_text()` (@thomasp85, #4367) + * `geom_tile()` now correctly recognises missing data in `xmin`, `xmax`, `ymin`, and `ymax` (@thomasp85 and @sigmapi, #4495) diff --git a/R/position-stack.r b/R/position-stack.r index 98ad6e5db1..565d311e46 100644 --- a/R/position-stack.r +++ b/R/position-stack.r @@ -165,7 +165,7 @@ PositionStack <- ggproto("PositionStack", Position, data$ymax <- switch(params$var, y = data$y, - ymax = ifelse(data$ymax == 0, data$ymin, data$ymax) + ymax = as.numeric(ifelse(data$ymax == 0, data$ymin, data$ymax)) ) data <- remove_missing( @@ -225,8 +225,8 @@ pos_stack <- function(df, width, vjust = 1, fill = FALSE) { ymin <- pmin(heights[-n], heights[-1]) ymax <- pmax(heights[-n], heights[-1]) df$y <- (1 - vjust) * ymin + vjust * ymax - df$ymin <- ifelse(max_is_lower, ymax, ymin) - df$ymax <- ifelse(max_is_lower, ymin, ymax) + df$ymin <- as.numeric(ifelse(max_is_lower, ymax, ymin)) + df$ymax <- as.numeric(ifelse(max_is_lower, ymin, ymax)) df } From ec8a917fe71c3ed144b192f46c1a2747b93ca5ce Mon Sep 17 00:00:00 2001 From: Hadley Wickham Date: Thu, 3 Mar 2022 17:45:20 -0600 Subject: [PATCH 31/32] Workflow updates (#4747) * use_tidy_description() * use_tidy_github_actions() * Update website --- .github/workflows/R-CMD-check.yaml | 97 ++++++++++------------------ .github/workflows/pkgdown.yaml | 36 +++++++---- .github/workflows/pr-commands.yaml | 32 +++++---- .github/workflows/test-coverage.yaml | 11 ++-- DESCRIPTION | 50 +++++++------- _pkgdown.yml | 21 ++---- 6 files changed, 112 insertions(+), 135 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 0a9593bd02..9c9d6d6c86 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -1,4 +1,4 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help # # NOTE: This workflow is overkill for most R packages and @@ -12,10 +12,6 @@ on: name: R-CMD-check -# Increment this version when we want to clear cache -env: - cache-version: v6 - jobs: R-CMD-check: runs-on: ${{ matrix.config.os }} @@ -26,78 +22,53 @@ jobs: fail-fast: false matrix: config: - - {os: windows-latest, r: '4.1', vdiffr: true, xref: true} - - {os: macOS-latest, r: '4.1', vdiffr: true, xref: true} - - {os: ubuntu-18.04, r: 'devel', vdiffr: false, xref: true} - - {os: ubuntu-18.04, r: '4.1', vdiffr: true, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '4.0', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '3.6', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '3.5', vdiffr: false, xref: true, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '3.4', vdiffr: false, xref: false, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} - - {os: ubuntu-18.04, r: '3.3', vdiffr: false, xref: false, rspm: "https://packagemanager.rstudio.com/cran/__linux__/bionic/latest"} + - {os: macOS-latest, r: 'release'} + + - {os: windows-latest, r: 'release'} + # Use 3.6 to trigger usage of RTools35 + - {os: windows-latest, r: '3.6'} + + # Use latest ubuntu to make it easier to install sf dependencies + - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'} + - {os: ubuntu-latest, r: 'release'} + - {os: ubuntu-latest, r: 'oldrel-1'} + - {os: ubuntu-latest, r: 'oldrel-2'} + - {os: ubuntu-latest, r: 'oldrel-3'} + - {os: ubuntu-latest, r: 'oldrel-4'} env: - R_REMOTES_NO_ERRORS_FROM_WARNINGS: true - RSPM: ${{ matrix.config.rspm }} - # don't treat missing suggested packages as error + GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} + R_KEEP_PKG_SOURCE: yes _R_CHECK_FORCE_SUGGESTS_: false # Some packages might unavailable on the older versions, so let's ignore xref warnings - _R_CHECK_RD_XREFS_: ${{ matrix.config.xref }} + _R_CHECK_RD_XREFS_: false # Runs vdiffr test only on the latest version of R - VDIFFR_RUN_TESTS: ${{ matrix.config.vdiffr }} + VDIFFR_RUN_TESTS: ${{ matrix.config.r == 'release' }} VDIFFR_LOG_PATH: "../vdiffr.Rout.fail" steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-r@master + - uses: r-lib/actions/setup-pandoc@v2 + + - uses: r-lib/actions/setup-r@v2 with: r-version: ${{ matrix.config.r }} http-user-agent: ${{ matrix.config.http-user-agent }} + use-public-rspm: true - - uses: r-lib/actions/setup-pandoc@master - - - name: Query dependencies - run: | - install.packages('remotes') - saveRDS(remotes::dev_package_deps(dependencies = TRUE), "depends.Rds", version = 2) - shell: Rscript {0} - - - name: Cache R packages - if: runner.os != 'Windows' - uses: actions/cache@v1 + - uses: r-lib/actions/setup-r-dependencies@v2 with: - path: ${{ env.R_LIBS_USER }} - key: ${{ env.cache-version }}-${{ runner.os }}-r-${{ matrix.config.r }}-${{ hashFiles('depends.Rds') }} - restore-keys: ${{ env.cache-version }}-${{ runner.os }}-r-${{ matrix.config.r }}- - - - name: Install system dependencies on Linux - if: runner.os == 'Linux' - run: | - while read -r cmd - do - eval sudo $cmd - done < <(Rscript -e 'writeLines(remotes::system_requirements("ubuntu", "18.04"))') - - name: Install system dependencies on macOS - if: runner.os == 'macOS' - run: | - # XQuartz is needed by vdiffr - brew install xquartz - # Use only binary packages - echo 'options(pkgType = "binary")' >> ~/.Rprofile - - name: Install dependencies - run: | - remotes::install_deps(dependencies = TRUE) - remotes::install_cran("rcmdcheck") - shell: Rscript {0} - - - name: Check - run: rcmdcheck::rcmdcheck(args = "--no-manual", error_on = "warning", check_dir = "check") - shell: Rscript {0} + extra-packages: > + any::rcmdcheck, + maps=?ignore-before-r=3.5.0, + Hmisc=?ignore-before-r=3.6.0, + mapproj=?ignore-before-r=3.5.0, + multcomp=?ignore-before-r=3.5.0, + quantreg=?ignore-before-r=3.5.0, + interp=?ignore-before-r=3.5.0 + needs: check - - name: Upload check results - if: failure() - uses: actions/upload-artifact@master + - uses: r-lib/actions/check-r-package@v2 with: - name: ${{ runner.os }}-r${{ matrix.config.r }}-results - path: check + upload-snapshots: true diff --git a/.github/workflows/pkgdown.yaml b/.github/workflows/pkgdown.yaml index 6d10b7c806..0b2602168b 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -1,34 +1,46 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: - types: [published] branches: [main, master] - tags: ['*'] + pull_request: + branches: [main, master] + release: + types: [published] + workflow_dispatch: name: pkgdown jobs: pkgdown: runs-on: ubuntu-latest + # Only restrict concurrency for non-PR jobs + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-pandoc@v1 + - uses: r-lib/actions/setup-pandoc@v2 - - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true - - uses: r-lib/actions/setup-r-dependencies@v1 + - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: pkgdown + extra-packages: any::pkgdown, local::. needs: website - - name: Deploy package - run: | - git config --local user.name "$GITHUB_ACTOR" - git config --local user.email "$GITHUB_ACTOR@users.noreply.github.com" - Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) + shell: Rscript {0} + + - name: Deploy to GitHub pages 🚀 + if: github.event_name != 'pull_request' + uses: JamesIves/github-pages-deploy-action@4.1.4 + with: + clean: false + branch: gh-pages + folder: docs diff --git a/.github/workflows/pr-commands.yaml b/.github/workflows/pr-commands.yaml index 1cdafbf7e4..97271eb29f 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -1,4 +1,4 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: issue_comment: @@ -8,7 +8,7 @@ name: Commands jobs: document: - if: startsWith(github.event.comment.body, '/document') + if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/document') }} name: document runs-on: ubuntu-latest env: @@ -16,20 +16,22 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/pr-fetch@v1 + - uses: r-lib/actions/pr-fetch@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true - - uses: r-lib/actions/setup-r-dependencies@v1 + - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: roxygen2 + extra-packages: any::roxygen2 + needs: pr-document - name: Document - run: Rscript -e 'roxygen2::roxygenise()' + run: roxygen2::roxygenise() + shell: Rscript {0} - name: commit run: | @@ -38,12 +40,12 @@ jobs: git add man/\* NAMESPACE git commit -m 'Document' - - uses: r-lib/actions/pr-push@v1 + - uses: r-lib/actions/pr-push@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} style: - if: startsWith(github.event.comment.body, '/style') + if: ${{ github.event.issue.pull_request && (github.event.comment.author_association == 'MEMBER' || github.event.comment.author_association == 'OWNER') && startsWith(github.event.comment.body, '/style') }} name: style runs-on: ubuntu-latest env: @@ -51,17 +53,19 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/pr-fetch@v1 + - uses: r-lib/actions/pr-fetch@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} - - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-r@v2 - name: Install dependencies - run: Rscript -e 'install.packages("styler")' + run: install.packages("styler") + shell: Rscript {0} - name: Style - run: Rscript -e 'styler::style_pkg()' + run: styler::style_pkg() + shell: Rscript {0} - name: commit run: | @@ -70,6 +74,6 @@ jobs: git add \*.R git commit -m 'Style' - - uses: r-lib/actions/pr-push@v1 + - uses: r-lib/actions/pr-push@v2 with: repo-token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 3c0da1c97c..4b65418291 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -1,4 +1,4 @@ -# Workflow derived from https://github.com/r-lib/actions/tree/master/examples +# Workflow derived from https://github.com/r-lib/actions/tree/v2/examples # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help on: push: @@ -17,14 +17,15 @@ jobs: steps: - uses: actions/checkout@v2 - - uses: r-lib/actions/setup-r@v1 + - uses: r-lib/actions/setup-r@v2 with: use-public-rspm: true - - uses: r-lib/actions/setup-r-dependencies@v1 + - uses: r-lib/actions/setup-r-dependencies@v2 with: - extra-packages: covr + extra-packages: any::covr + needs: coverage - name: Test coverage - run: covr::codecov() + run: covr::codecov(quiet = FALSE) shell: Rscript {0} diff --git a/DESCRIPTION b/DESCRIPTION index 89af5c1bd2..4488507841 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,18 +1,14 @@ Package: ggplot2 -Version: 3.3.5.9000 Title: Create Elegant Data Visualisations Using the Grammar of Graphics -Description: A system for 'declaratively' creating graphics, - based on "The Grammar of Graphics". You provide the data, tell 'ggplot2' - how to map variables to aesthetics, what graphical primitives to use, - and it takes care of the details. +Version: 3.3.5.9000 Authors@R: c( - person("Hadley", "Wickham", , "hadley@rstudio.com", "aut", + person("Hadley", "Wickham", , "hadley@rstudio.com", role = "aut", comment = c(ORCID = "0000-0003-4757-117X")), - person("Winston", "Chang", , role = "aut", + person("Winston", "Chang", role = "aut", comment = c(ORCID = "0000-0002-1576-2126")), - person("Lionel", "Henry", , role = "aut"), - person("Thomas Lin", "Pedersen", , "thomas.pedersen@rstudio.com", - role = c("aut", "cre"), comment = c(ORCID = "0000-0002-5147-4711")), + person("Lionel", "Henry", role = "aut"), + person("Thomas Lin", "Pedersen", , "thomas.pedersen@rstudio.com", role = c("aut", "cre"), + comment = c(ORCID = "0000-0002-5147-4711")), person("Kohske", "Takahashi", role = "aut"), person("Claus", "Wilke", role = "aut", comment = c(ORCID = "0000-0002-7470-9261")), @@ -23,7 +19,14 @@ Authors@R: c( person("Dewey", "Dunnington", role = "aut", comment = c(ORCID = "0000-0002-9415-4582")), person("RStudio", role = c("cph", "fnd")) - ) + ) +Description: A system for 'declaratively' creating graphics, based on "The + Grammar of Graphics". You provide the data, tell 'ggplot2' how to map + variables to aesthetics, what graphical primitives to use, and it + takes care of the details. +License: MIT + file LICENSE +URL: https://ggplot2.tidyverse.org, https://github.com/tidyverse/ggplot2 +BugReports: https://github.com/tidyverse/ggplot2/issues Depends: R (>= 3.3) Imports: @@ -42,7 +45,6 @@ Imports: withr (>= 2.0.0) Suggests: covr, - ragg, dplyr, ggplot2movies, hexbin, @@ -58,6 +60,7 @@ Suggests: nlme, profvis, quantreg, + ragg, RColorBrewer, rgeos, rmarkdown, @@ -67,11 +70,16 @@ Suggests: testthat (>= 3.0.0), vdiffr (>= 1.0.0), xml2 -Enhances: sp -License: MIT + file LICENSE -URL: https://ggplot2.tidyverse.org, https://github.com/tidyverse/ggplot2 -BugReports: https://github.com/tidyverse/ggplot2/issues +Enhances: + sp +VignetteBuilder: + knitr +Config/Needs/website: ggtext, tidyr, forcats, tidyverse/tidytemplate +Config/testthat/edition: 3 +Encoding: UTF-8 LazyData: true +Roxygen: list(markdown = TRUE) +RoxygenNote: 7.1.1 Collate: 'ggproto.r' 'ggplot-global.R' @@ -265,13 +273,3 @@ Collate: 'utilities-tidy-eval.R' 'zxx.r' 'zzz.r' -VignetteBuilder: knitr -RoxygenNote: 7.1.1 -Roxygen: list(markdown = TRUE) -Encoding: UTF-8 -Config/Needs/website: - ggtext, - tidyr, - forcats, - tidyverse/tidytemplate -Config/testthat/edition: 3 diff --git a/_pkgdown.yml b/_pkgdown.yml index 7290c01f6f..868360f66d 100644 --- a/_pkgdown.yml +++ b/_pkgdown.yml @@ -2,21 +2,16 @@ url: https://ggplot2.tidyverse.org template: package: tidytemplate - params: - docsearch: - api_key: e1261f3df95d2d4704c626ff11a4b536 - index_name: tidyverse_ggplot2 + bootstrap: 5 + + includes: + in_header: | + development: mode: auto authors: - Winston Chang: - href: https://github.com/wch - Lionel Henry: - href: https://github.com/lionel- - Thomas Lin Pedersen: - href: https://data-imaginist.com Claus Wilke: href: https://clauswilke.com Kara Woo: @@ -27,7 +22,6 @@ authors: href: https://fishandwhistle.net home: - strip_header: true links: - text: Learn more href: https://r4ds.had.co.nz/data-visualisation.html @@ -268,7 +262,6 @@ articles: - articles/faq-reordering - articles/faq-bars - news: releases: - text: "Version 3.3.0" @@ -290,10 +283,8 @@ news: navbar: structure: - right: [reference, news, articles, extensions, github] - left: [] + left: [reference, news, articles, extensions] components: - home: ~ extensions: text: Extensions href: https://exts.ggplot2.tidyverse.org/gallery/ From 1b2a6d0cd46a661d83141fc23936b18aa1c18723 Mon Sep 17 00:00:00 2001 From: Thomas Lin Pedersen Date: Fri, 4 Mar 2022 13:20:08 +0100 Subject: [PATCH 32/32] remove stringsAsFactor for the mapped_discrete as.data.frame method --- R/scale-discrete-.r | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/R/scale-discrete-.r b/R/scale-discrete-.r index 5c7bef8134..555b902db1 100644 --- a/R/scale-discrete-.r +++ b/R/scale-discrete-.r @@ -170,6 +170,6 @@ c.mapped_discrete <- function(..., recursive = FALSE) { new_mapped_discrete(NextMethod()) } #' @export -as.data.frame.mapped_discrete <- function (x, ..., stringsAsFactors = default.stringsAsFactors()) { - as.data.frame.vector(x = unclass(x), ..., stringsAsFactors = stringsAsFactors) +as.data.frame.mapped_discrete <- function (x, ...) { + as.data.frame.vector(x = unclass(x), ...) }