diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 50a86ee67e..9c9d6d6c86 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -1,17 +1,17 @@ +# 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 +# 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 -# Increment this version when we want to clear cache -env: - cache-version: v6 - jobs: R-CMD-check: runs-on: ${{ matrix.config.os }} @@ -22,81 +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: 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: 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} - - - name: Upload check results - if: failure() - uses: actions/upload-artifact@master + 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 + + - 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 8da22c8a07..0b2602168b 100644 --- a/.github/workflows/pkgdown.yaml +++ b/.github/workflows/pkgdown.yaml @@ -1,60 +1,46 @@ +# 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: - branches: - - master + branches: [main, master] + pull_request: + branches: [main, master] release: types: [published] + workflow_dispatch: name: pkgdown jobs: pkgdown: - runs-on: ubuntu-18.04 + runs-on: ubuntu-latest + # Only restrict concurrency for non-PR jobs + concurrency: + group: pkgdown-${{ github.event_name != 'pull_request' || github.run_id }} 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} + - uses: r-lib/actions/setup-pandoc@v2 - - name: Restore R package cache - uses: actions/cache@v2 + - uses: r-lib/actions/setup-r@v2 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} + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::pkgdown, local::. + needs: website - - name: Install dependencies - run: | - pak::local_install_dev_deps(upgrade = TRUE, dependencies = c("all", "Config/Needs/website")) - pak::pkg_install("pkgdown") + - name: Build site + run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE) shell: Rscript {0} - - name: Install package - run: R CMD INSTALL . - - - name: Deploy package - run: | - git config --local user.email "actions@github.com" - git config --local user.name "GitHub Actions" - Rscript -e 'pkgdown::deploy_to_branch(new_process = FALSE)' + - 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 e5edf9f778..97271eb29f 100644 --- a/.github/workflows/pr-commands.yaml +++ b/.github/workflows/pr-commands.yaml @@ -1,55 +1,79 @@ +# 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: types: [created] + 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: macOS-latest + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 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 - - name: Install dependencies - run: Rscript -e 'install.packages(c("remotes", "roxygen2"))' -e 'remotes::install_deps(dependencies = TRUE)' + + - uses: r-lib/actions/setup-r@v2 + with: + use-public-rspm: true + + - uses: r-lib/actions/setup-r-dependencies@v2 + with: + extra-packages: any::roxygen2 + needs: pr-document + - name: Document - run: Rscript -e 'roxygen2::roxygenise()' + run: roxygen2::roxygenise() + shell: Rscript {0} + - 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 + + - 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: macOS-latest + runs-on: ubuntu-latest env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} 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: | - 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 + + - 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 e3c16455cb..4b65418291 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -1,58 +1,31 @@ +# 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: - 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 + - uses: r-lib/actions/setup-r@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@v2 + with: + 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 9f4bad40c9..4488507841 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,18 +1,14 @@ Package: ggplot2 -Version: 3.3.5 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,20 +60,26 @@ Suggests: nlme, profvis, quantreg, + ragg, RColorBrewer, rgeos, rmarkdown, 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 -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,12 +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 diff --git a/NEWS.md b/NEWS.md index 950c3f555a..6579c613b1 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,58 @@ +# 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) + +* `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) + +* Axes are now added correctly in `facet_wrap()` when `as.table = FALSE` + (@thomasp85, #4553) + +* 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) + +* 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) + +* 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) + +* `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) + +* `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) + +* `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) + +* `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 that surfaced with the 3.3.4 release @@ -85,7 +140,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) 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) 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/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/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/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/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-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/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-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/R/geom-hex.r b/R/geom-hex.r index 6879038724..e28e1cbe74 100644 --- a/R/geom-hex.r +++ b/R/geom-hex.r @@ -54,20 +54,50 @@ geom_hex <- function(mapping = NULL, data = NULL, #' @usage NULL #' @export GeomHex <- ggproto("GeomHex", Geom, - draw_group = function(data, panel_params, coord) { - if (!inherits(coord, "CoordCartesian")) { - abort("geom_hex() only works with Cartesian coordinates") + draw_group = function(data, panel_params, coord, lineend = "butt", + linejoin = "mitre", linemitre = 10) { + 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, fill = alpha(coords$fill, coords$alpha), lwd = coords$size * .pt, - lty = coords$linetype - ) + lty = coords$linetype, + lineend = lineend, + linejoin = linejoin, + linemitre = linemitre + ), + default.units = "native", + id.lengths = rep.int(6, n) )) }, @@ -93,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/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-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 ) ) 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-segment.r b/R/geom-segment.r index d21ec10ead..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). @@ -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..0111c6fd5b 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 @@ -126,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) { @@ -158,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" @@ -208,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/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-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 ) 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/guide-legend.r b/R/guide-legend.r index 4fe9eb2b62..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) } @@ -634,7 +639,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) } 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/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/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/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/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/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 } 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 diff --git a/R/scale-.r b/R/scale-.r index 3fa2f6cbde..91c35cd35f 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. @@ -1082,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)) { 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-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), ...) } 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-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/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/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, 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/README.Rmd b/README.Rmd index 39180a5b5c..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 @@ -38,7 +40,7 @@ devtools::install_github("tidyverse/ggplot2") ## Cheatsheet - + ## Usage diff --git a/README.md b/README.md index da3a046e0c..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 @@ -33,7 +35,7 @@ devtools::install_github("tidyverse/ggplot2") ## Cheatsheet - + ## Usage diff --git a/_pkgdown.yml b/_pkgdown.yml index 8f046d9152..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 @@ -118,6 +112,7 @@ reference: - expand_limits - expansion - starts_with("scale_") + - get_alt_text - title: "Guides: axes and legends" desc: > @@ -267,7 +262,6 @@ articles: - articles/faq-reordering - articles/faq-bars - news: releases: - text: "Version 3.3.0" @@ -289,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/ 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/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/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/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/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/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 diff --git a/man/geom_segment.Rd b/man/geom_segment.Rd index 799adac1c3..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.} @@ -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/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/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/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{ 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/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 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_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_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..3f29ab5500 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. @@ -113,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_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..9156950f0a 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. @@ -80,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_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. 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)) 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/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/_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-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/_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-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/_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 @@ - - - - - - + + + + + + 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..4c3e055ea8 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)) @@ -15,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))) + 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 b510c3ced2..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, @@ -31,6 +29,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-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 ba46588a79..89497aba46 100644 --- a/tests/testthat/test-coord-map.R +++ b/tests/testthat/test-coord-map.R @@ -1,9 +1,7 @@ -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 +11,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 +25,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-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..bf99bbec00 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) @@ -82,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")) 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..269fea8e62 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 @@ -133,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") 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..82465e2183 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)) + @@ -17,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() + ) }) diff --git a/tests/testthat/test-geom-hline-vline-abline.R b/tests/testthat/test-geom-hline-vline-abline.R index 746bfff144..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 ------------------------------------------------------------ @@ -29,6 +27,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() + 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..ded534a0d2 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") @@ -202,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) + ) +}) 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..7247cac8b1 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()", { @@ -179,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", { 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 b8af871e99..05da3e21d7 100644 --- a/tests/testthat/test-scale-manual.r +++ b/tests/testthat/test-scale-manual.r @@ -1,9 +1,11 @@ -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 +89,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")) +}) 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 61df774756..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", { @@ -32,7 +37,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 +45,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", { 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)