diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 9fd3500247..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 cask install 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 c1a0c04cb5..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 cask install xquartz + brew install xquartz - name: Install dependencies run: | diff --git a/DESCRIPTION b/DESCRIPTION index f8eb4760de..cc79750ea0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -46,6 +46,7 @@ Suggests: ggplot2movies, hexbin, Hmisc, + interp, knitr, lattice, mapproj, diff --git a/R/geom-contour.r b/R/geom-contour.r index 17ac1c1733..cc25a70da4 100644 --- a/R/geom-contour.r +++ b/R/geom-contour.r @@ -1,12 +1,16 @@ #' 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 [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") @@ -15,9 +19,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 @@ -47,6 +51,22 @@ #' v + geom_contour(colour = "red") #' v + geom_raster(aes(fill = density)) + #' geom_contour(colour = "white") +#' +#' # Irregular data +#' 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() + +#' geom_point(data = origdata) +#' } else +#' message("Irregular data requires the 'interp' package") #' } geom_contour <- function(mapping = NULL, data = NULL, stat = "contour", position = "identity", 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/geom_contour.Rd b/man/geom_contour.Rd index e3b0ee8f03..1277d9b84b 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,16 @@ 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[interp:interp]{interp::interp()}} function from the \code{interp} package +(or one of the interpolating functions from the \code{akima} package.) } \section{Aesthetics}{ @@ -236,6 +240,22 @@ 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("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() + + geom_point(data = origdata) +} else + message("Irregular data requires the 'interp' package") } } \seealso{ 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 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()) 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