From 4b86c18829f605dea48a0f73c688ad449fdc7d74 Mon Sep 17 00:00:00 2001 From: Duncan Murdoch Date: Sun, 24 Jan 2021 20:11:38 -0500 Subject: [PATCH 1/6] Improve docs for geom_contour as discussed in issue #4324 --- DESCRIPTION | 1 + R/geom-contour.r | 36 +++++++++++++++++++++++++++--------- man/geom_contour.Rd | 36 +++++++++++++++++++++++++++--------- man/geom_density_2d.Rd | 6 +++--- 4 files changed, 58 insertions(+), 21 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index f8eb4760de..a40b7a816f 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -41,6 +41,7 @@ Imports: tibble, withr (>= 2.0.0) Suggests: + akima, covr, dplyr, ggplot2movies, diff --git a/R/geom-contour.r b/R/geom-contour.r index 17ac1c1733..ab0a981265 100644 --- a/R/geom-contour.r +++ b/R/geom-contour.r @@ -1,12 +1,15 @@ #' 2D contours of a 3D surface #' #' ggplot2 can not draw true 3D surfaces, but you can use `geom_contour()`, -#' `geom_contour_filled()`, and [geom_tile()] to visualise 3D surfaces in 2D. -#' To specify a valid surface, the data must contain `x`, `y`, and `z` coordinates, -#' and each unique combination of `x` and `y` can appear exactly once. Contouring -#' tends to work best when `x` and `y` form a (roughly) evenly -#' spaced grid. If your data is not evenly spaced, you may want to interpolate -#' to a grid before visualising, see [geom_density_2d()]. +#' `geom_contour_filled()`, and [geom_tile()] to visualise 3D surfaces in 2D. To +#' specify a valid surface, the data must contain `x`, `y`, and `z` coordinates, +#' and each unique combination of `x` and `y` can appear at most once. +#' Contouring requires that the points can be rearranged so that the `z` values +#' form a matrix, with rows corresponding to unique `x` values, and columns +#' corresponding to unique `y` values. Missing entries are allowed, but contouring +#' will only be done on cells of the grid with all four `z` values present. If +#' your data is irregular, you can interpolate to a grid before visualising +#' using the [akima::interp()] function from the `akima` package. #' #' @eval rd_aesthetics("geom", "contour") #' @eval rd_aesthetics("geom", "contour_filled") @@ -15,9 +18,9 @@ #' @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 Numeric vector to set the contour breaks. 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 @@ -48,6 +51,21 @@ #' v + geom_raster(aes(fill = density)) + #' geom_contour(colour = "white") #' } +#' # Irregular data +#' if (requireNamespace("akima")) { +#' fit <- lm(mpg ~ polym(disp, hp, degree = 2), data = mtcars) +#' grid <- akima::interp(mtcars$disp, mtcars$hp, predict(fit), +#' duplicate = "mean", nx = 100, ny = 100) +#' griddf <- subset(data.frame(disp = rep(grid$x, nrow(grid$z)), +#' hp = rep(grid$y, each = ncol(grid$z)), +#' mpg = as.numeric(grid$z)), +#' !is.na(mpg)) +#' ggplot(griddf, aes(disp, hp, z = mpg)) + +#' geom_contour_filled() + +#' labs(fill = "MPG") + +#' geom_point(data = mtcars, aes(disp, hp)) +#' } else +#' message("Irregular data requires the 'akima' package") geom_contour <- function(mapping = NULL, data = NULL, stat = "contour", position = "identity", ..., diff --git a/man/geom_contour.Rd b/man/geom_contour.Rd index e3b0ee8f03..aaf47768b3 100644 --- a/man/geom_contour.Rd +++ b/man/geom_contour.Rd @@ -102,9 +102,9 @@ 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}{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{lineend}{Line end style (round, butt, square).} @@ -130,12 +130,15 @@ the default plot specification, e.g. \code{\link[=borders]{borders()}}.} } \description{ ggplot2 can not draw true 3D surfaces, but you can use \code{geom_contour()}, -\code{geom_contour_filled()}, and \code{\link[=geom_tile]{geom_tile()}} to visualise 3D surfaces in 2D. -To specify a valid surface, the data must contain \code{x}, \code{y}, and \code{z} coordinates, -and each unique combination of \code{x} and \code{y} can appear exactly once. Contouring -tends to work best when \code{x} and \code{y} form a (roughly) evenly -spaced grid. If your data is not evenly spaced, you may want to interpolate -to a grid before visualising, see \code{\link[=geom_density_2d]{geom_density_2d()}}. +\code{geom_contour_filled()}, and \code{\link[=geom_tile]{geom_tile()}} to visualise 3D surfaces in 2D. To +specify a valid surface, the data must contain \code{x}, \code{y}, and \code{z} coordinates, +and each unique combination of \code{x} and \code{y} can appear at most once. +Contouring requires that the points can be rearranged so that the \code{z} values +form a matrix, with rows corresponding to unique \code{x} values, and columns +corresponding to unique \code{y} values. Missing entries are allowed, but contouring +will only be done on cells of the grid with all four \code{z} values present. If +your data is irregular, you can interpolate to a grid before visualising +using the \code{\link[akima:interp]{akima::interp()}} function from the \code{akima} package. } \section{Aesthetics}{ @@ -237,6 +240,21 @@ v + geom_contour(colour = "red") v + geom_raster(aes(fill = density)) + geom_contour(colour = "white") } +# Irregular data +if (requireNamespace("akima")) { + fit <- lm(mpg ~ polym(disp, hp, degree = 2), data = mtcars) + grid <- akima::interp(mtcars$disp, mtcars$hp, predict(fit), + duplicate = "mean", nx = 100, ny = 100) + griddf <- subset(data.frame(disp = rep(grid$x, nrow(grid$z)), + hp = rep(grid$y, each = ncol(grid$z)), + mpg = as.numeric(grid$z)), + !is.na(mpg)) + ggplot(griddf, aes(disp, hp, z = mpg)) + + geom_contour_filled() + + labs(fill = "MPG") + + geom_point(data = mtcars, aes(disp, hp)) +} else + message("Irregular data requires the 'akima' package") } \seealso{ \code{\link[=geom_density_2d]{geom_density_2d()}}: 2d density contours diff --git a/man/geom_density_2d.Rd b/man/geom_density_2d.Rd index c9c0ea7511..c0daf09211 100644 --- a/man/geom_density_2d.Rd +++ b/man/geom_density_2d.Rd @@ -99,9 +99,9 @@ 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}}{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{contour_var}{Character string identifying the variable to contour From 86f35b19c741e06ade279396b64e921412002a88 Mon Sep 17 00:00:00 2001 From: Duncan Murdoch Date: Mon, 25 Jan 2021 06:41:03 -0500 Subject: [PATCH 2/6] Stop default testing of new example. --- R/geom-contour.r | 3 ++- man/geom_contour.Rd | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/R/geom-contour.r b/R/geom-contour.r index ab0a981265..18f4fabd48 100644 --- a/R/geom-contour.r +++ b/R/geom-contour.r @@ -50,7 +50,7 @@ #' v + geom_contour(colour = "red") #' v + geom_raster(aes(fill = density)) + #' geom_contour(colour = "white") -#' } +#' #' # Irregular data #' if (requireNamespace("akima")) { #' fit <- lm(mpg ~ polym(disp, hp, degree = 2), data = mtcars) @@ -66,6 +66,7 @@ #' geom_point(data = mtcars, aes(disp, hp)) #' } else #' message("Irregular data requires the 'akima' package") +#' } geom_contour <- function(mapping = NULL, data = NULL, stat = "contour", position = "identity", ..., diff --git a/man/geom_contour.Rd b/man/geom_contour.Rd index aaf47768b3..e1b6251568 100644 --- a/man/geom_contour.Rd +++ b/man/geom_contour.Rd @@ -239,7 +239,7 @@ v + geom_contour(aes(colour = after_stat(level))) v + geom_contour(colour = "red") v + geom_raster(aes(fill = density)) + geom_contour(colour = "white") -} + # Irregular data if (requireNamespace("akima")) { fit <- lm(mpg ~ polym(disp, hp, degree = 2), data = mtcars) @@ -256,6 +256,7 @@ if (requireNamespace("akima")) { } else message("Irregular data requires the 'akima' package") } +} \seealso{ \code{\link[=geom_density_2d]{geom_density_2d()}}: 2d density contours } From dd409ce80f7f28954c7555a2bf493c7bb15628f8 Mon Sep 17 00:00:00 2001 From: Duncan Murdoch Date: Tue, 26 Jan 2021 10:18:43 -0500 Subject: [PATCH 3/6] Recommend interp instead of akima --- DESCRIPTION | 2 +- R/geom-contour.r | 27 ++++++++++++++------------- man/geom_contour.Rd | 27 ++++++++++++++------------- 3 files changed, 29 insertions(+), 27 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index a40b7a816f..cc79750ea0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -41,12 +41,12 @@ Imports: tibble, withr (>= 2.0.0) Suggests: - akima, covr, dplyr, ggplot2movies, hexbin, Hmisc, + interp, knitr, lattice, mapproj, diff --git a/R/geom-contour.r b/R/geom-contour.r index 18f4fabd48..cc25a70da4 100644 --- a/R/geom-contour.r +++ b/R/geom-contour.r @@ -9,7 +9,8 @@ #' corresponding to unique `y` values. Missing entries are allowed, but contouring #' will only be done on cells of the grid with all four `z` values present. If #' your data is irregular, you can interpolate to a grid before visualising -#' using the [akima::interp()] function from the `akima` package. +#' using the [interp::interp()] function from the `interp` package +#' (or one of the interpolating functions from the `akima` package.) #' #' @eval rd_aesthetics("geom", "contour") #' @eval rd_aesthetics("geom", "contour_filled") @@ -52,20 +53,20 @@ #' geom_contour(colour = "white") #' #' # Irregular data -#' if (requireNamespace("akima")) { -#' fit <- lm(mpg ~ polym(disp, hp, degree = 2), data = mtcars) -#' grid <- akima::interp(mtcars$disp, mtcars$hp, predict(fit), -#' duplicate = "mean", nx = 100, ny = 100) -#' griddf <- subset(data.frame(disp = rep(grid$x, nrow(grid$z)), -#' hp = rep(grid$y, each = ncol(grid$z)), -#' mpg = as.numeric(grid$z)), -#' !is.na(mpg)) -#' ggplot(griddf, aes(disp, hp, z = mpg)) + +#' if (requireNamespace("interp")) { +#' # Use a dataset from the interp package +#' data(franke, package = "interp") +#' origdata <- as.data.frame(interp::franke.data(1, 1, franke)) +#' grid <- with(origdata, interp::interp(x, y, z)) +#' griddf <- subset(data.frame(x = rep(grid$x, nrow(grid$z)), +#' y = rep(grid$y, each = ncol(grid$z)), +#' z = as.numeric(grid$z)), +#' !is.na(z)) +#' ggplot(griddf, aes(x, y, z = z)) + #' geom_contour_filled() + -#' labs(fill = "MPG") + -#' geom_point(data = mtcars, aes(disp, hp)) +#' geom_point(data = origdata) #' } else -#' message("Irregular data requires the 'akima' package") +#' message("Irregular data requires the 'interp' package") #' } geom_contour <- function(mapping = NULL, data = NULL, stat = "contour", position = "identity", diff --git a/man/geom_contour.Rd b/man/geom_contour.Rd index e1b6251568..1277d9b84b 100644 --- a/man/geom_contour.Rd +++ b/man/geom_contour.Rd @@ -138,7 +138,8 @@ form a matrix, with rows corresponding to unique \code{x} values, and columns corresponding to unique \code{y} values. Missing entries are allowed, but contouring will only be done on cells of the grid with all four \code{z} values present. If your data is irregular, you can interpolate to a grid before visualising -using the \code{\link[akima:interp]{akima::interp()}} function from the \code{akima} package. +using the \code{\link[interp:interp]{interp::interp()}} function from the \code{interp} package +(or one of the interpolating functions from the \code{akima} package.) } \section{Aesthetics}{ @@ -241,20 +242,20 @@ v + geom_raster(aes(fill = density)) + geom_contour(colour = "white") # Irregular data -if (requireNamespace("akima")) { - fit <- lm(mpg ~ polym(disp, hp, degree = 2), data = mtcars) - grid <- akima::interp(mtcars$disp, mtcars$hp, predict(fit), - duplicate = "mean", nx = 100, ny = 100) - griddf <- subset(data.frame(disp = rep(grid$x, nrow(grid$z)), - hp = rep(grid$y, each = ncol(grid$z)), - mpg = as.numeric(grid$z)), - !is.na(mpg)) - ggplot(griddf, aes(disp, hp, z = mpg)) + +if (requireNamespace("interp")) { + # Use a dataset from the interp package + data(franke, package = "interp") + origdata <- as.data.frame(interp::franke.data(1, 1, franke)) + grid <- with(origdata, interp::interp(x, y, z)) + griddf <- subset(data.frame(x = rep(grid$x, nrow(grid$z)), + y = rep(grid$y, each = ncol(grid$z)), + z = as.numeric(grid$z)), + !is.na(z)) + ggplot(griddf, aes(x, y, z = z)) + geom_contour_filled() + - labs(fill = "MPG") + - geom_point(data = mtcars, aes(disp, hp)) + geom_point(data = origdata) } else - message("Irregular data requires the 'akima' package") + message("Irregular data requires the 'interp' package") } } \seealso{ From c4918016f3cb99650dbc31a999a91975a471ce21 Mon Sep 17 00:00:00 2001 From: Cui Xueqin Date: Wed, 27 Jan 2021 07:45:56 +0800 Subject: [PATCH 4/6] Remove leading space in document (#4329) * Remove leading space in document Remove leading space in the document of position_jitterdodge() * Document Co-authored-by: GitHub Actions --- R/position-jitterdodge.R | 2 +- man/position_jitterdodge.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/position-jitterdodge.R b/R/position-jitterdodge.R index 0e078e6cf9..abb5dd8ace 100644 --- a/R/position-jitterdodge.R +++ b/R/position-jitterdodge.R @@ -13,7 +13,7 @@ #' @inheritParams position_jitter #' @export #' @examples -#' dsub <- diamonds[ sample(nrow(diamonds), 1000), ] +#' dsub <- diamonds[sample(nrow(diamonds), 1000), ] #' ggplot(dsub, aes(x = cut, y = carat, fill = clarity)) + #' geom_boxplot(outlier.size = 0) + #' geom_point(pch = 21, position = position_jitterdodge()) diff --git a/man/position_jitterdodge.Rd b/man/position_jitterdodge.Rd index 5e31830ae8..49d0ad55d0 100644 --- a/man/position_jitterdodge.Rd +++ b/man/position_jitterdodge.Rd @@ -35,7 +35,7 @@ This is primarily used for aligning points generated through a fill aesthetic supplied). } \examples{ -dsub <- diamonds[ sample(nrow(diamonds), 1000), ] +dsub <- diamonds[sample(nrow(diamonds), 1000), ] ggplot(dsub, aes(x = cut, y = carat, fill = clarity)) + geom_boxplot(outlier.size = 0) + geom_point(pch = 21, position = position_jitterdodge()) From 2389828a3527c478ade3117fc2b9c4755215613d Mon Sep 17 00:00:00 2001 From: Jim Hester Date: Thu, 28 Jan 2021 14:10:24 -0500 Subject: [PATCH 5/6] Fix deprecated 'brew cask' calls brew cask is now deprecated in favor of the `--cask` argument --- .github/workflows/R-CMD-check.yaml | 2 +- .github/workflows/test-coverage.yaml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 9fd3500247..dda84d2628 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -78,7 +78,7 @@ jobs: if: runner.os == 'macOS' run: | # XQuartz is needed by vdiffr - brew cask install xquartz + brew install --cask xquartz # Use only binary packages echo 'options(pkgType = "binary")' >> ~/.Rprofile diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index c1a0c04cb5..c7d7148f7e 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -41,7 +41,7 @@ jobs: - name: Install system dependencies on macOS run: | # XQuartz is needed by vdiffr - brew cask install xquartz + brew install --cask xquartz - name: Install dependencies run: | From 6e987edc122b56228b2f822ff0aec0c4d505df69 Mon Sep 17 00:00:00 2001 From: Hiroaki Yutani Date: Sat, 30 Jan 2021 09:03:14 +0900 Subject: [PATCH 6/6] Update vdiffr cases for sf 0.9-7 and fix forbidden "brew cask" (#4311) * Update vdiffr cases * Use `brew install` instead of `brew cask install` --- .github/workflows/R-CMD-check.yaml | 2 +- .github/workflows/test-coverage.yaml | 2 +- tests/figs/coord-sf/sf-polygons.svg | 8 ++++---- tests/figs/deps.txt | 2 +- tests/figs/geom-sf/north-carolina-county-boundaries.svg | 8 ++++---- 5 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index dda84d2628..bb0bf3c0f6 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -78,7 +78,7 @@ jobs: if: runner.os == 'macOS' run: | # XQuartz is needed by vdiffr - brew install --cask xquartz + brew install xquartz # Use only binary packages echo 'options(pkgType = "binary")' >> ~/.Rprofile diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index c7d7148f7e..3ba34d271c 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -41,7 +41,7 @@ jobs: - name: Install system dependencies on macOS run: | # XQuartz is needed by vdiffr - brew install --cask xquartz + brew install xquartz - name: Install dependencies run: | diff --git a/tests/figs/coord-sf/sf-polygons.svg b/tests/figs/coord-sf/sf-polygons.svg index a3b1b6928c..62c30c94df 100644 --- a/tests/figs/coord-sf/sf-polygons.svg +++ b/tests/figs/coord-sf/sf-polygons.svg @@ -39,25 +39,25 @@ 36.25 ° N -36.3 +36.30 ° N 36.35 ° N -36.4 +36.40 ° N 36.45 ° N -36.5 +36.50 ° N 36.55 ° N -36.6 +36.60 ° N diff --git a/tests/figs/deps.txt b/tests/figs/deps.txt index 0f64e23e67..8d7f66b6a1 100644 --- a/tests/figs/deps.txt +++ b/tests/figs/deps.txt @@ -1,3 +1,3 @@ - vdiffr-svg-engine: 1.0 -- vdiffr: 0.3.1 +- vdiffr: 0.3.3 - freetypeharfbuzz: 0.2.5 diff --git a/tests/figs/geom-sf/north-carolina-county-boundaries.svg b/tests/figs/geom-sf/north-carolina-county-boundaries.svg index 805823d951..429a3d8696 100644 --- a/tests/figs/geom-sf/north-carolina-county-boundaries.svg +++ b/tests/figs/geom-sf/north-carolina-county-boundaries.svg @@ -39,25 +39,25 @@ 36.25 ° N -36.3 +36.30 ° N 36.35 ° N -36.4 +36.40 ° N 36.45 ° N -36.5 +36.50 ° N 36.55 ° N -36.6 +36.60 ° N