diff --git a/NEWS.md b/NEWS.md index 0b0bf8b..73a0393 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,6 +2,13 @@ ## New features +- New argument `preset` for publication-grade output in one token: + `ggcorrplot(corr, preset = "publication")` sets white cell outlines and the + colorblind-safe `"RdBu"` palette. It only fills arguments you did not supply, so + anything you pass explicitly (e.g. `outline.color`, `colors`, `palette`) + overrides the preset. Defaults to `NULL` (no preset), leaving existing calls + unchanged. + - New argument `palette` to pick a built-in colorblind-safe diverging palette for the fill gradient: `ggcorrplot(corr, palette = "RdBu")` (or `"PuOr"`). Each is an 11-stop ramp with white at zero and the usual cool = negative / warm = diff --git a/R/ggcorrplot.R b/R/ggcorrplot.R index b30323d..783f002 100644 --- a/R/ggcorrplot.R +++ b/R/ggcorrplot.R @@ -43,6 +43,12 @@ #' ramp, white at zero, cool = negative / warm = positive) and takes precedence #' over \code{colors}. Defaults to \code{NULL} (use \code{colors}), so existing #' calls are unchanged. +#' @param preset optional name of a bundle of publication-grade defaults. The only +#' value, \code{"publication"}, sets white cell outlines and the colorblind-safe +#' \code{"RdBu"} palette in one token. It fills only the arguments you did not +#' supply, so any argument you pass explicitly (e.g. \code{outline.color}, +#' \code{colors}, \code{palette}) overrides the preset. Defaults to \code{NULL} +#' (no preset), leaving existing calls unchanged. #' @param outline.color the outline color of square or circle. Default value is #' "gray". #' @param hc.order logical value. If TRUE, correlation matrix will be hc.ordered @@ -246,7 +252,8 @@ ggcorrplot <- function(corr, lower.method = NULL, upper.method = NULL, hc.rect = NULL, - palette = NULL) { + palette = NULL, + preset = NULL) { type <- match.arg(type) method <- match.arg(method) # Resolve on insig[1] (not match.arg(insig)) so a caller passing the old @@ -256,6 +263,19 @@ ggcorrplot <- function(corr, # "stars" made c("pch", "blank") non-identical. Scalar/partial matching and the # default are unchanged. insig <- match.arg(insig[1], c("pch", "blank", "stars")) + # A preset is a bundle of "publication-grade" defaults (white cell outlines and + # a colorblind-safe diverging palette). It fills ONLY the arguments the caller + # did not supply -- detected with missing() BEFORE any reassignment, so an + # explicit argument always overrides the preset, and preset = NULL (the default) + # changes nothing. This must run above the palette block, which reassigns + # `colors`/`palette`. + if (!is.null(preset)) { + preset <- match.arg(preset, "publication") + if (missing(outline.color)) outline.color <- "white" + # Reach for the preset palette only when the caller pinned neither `palette` + # nor `colors`, so an explicit `colors` is never clobbered. + if (missing(palette) && missing(colors)) palette <- "RdBu" + } # A named colorblind-safe diverging palette is a convenience shortcut for # `colors`: when set (non-NULL, the default), it supplies the fill gradient and # takes precedence over `colors`. `palette = NULL` leaves `colors` untouched, so diff --git a/man/ggcorrplot.Rd b/man/ggcorrplot.Rd index eeeba0d..ac9ce87 100644 --- a/man/ggcorrplot.Rd +++ b/man/ggcorrplot.Rd @@ -44,7 +44,8 @@ ggcorrplot( lower.method = NULL, upper.method = NULL, hc.rect = NULL, - palette = NULL + palette = NULL, + preset = NULL ) cor_pmat(x, ..., use = c("pairwise.complete.obs", "everything")) @@ -196,6 +197,13 @@ ramp, white at zero, cool = negative / warm = positive) and takes precedence over \code{colors}. Defaults to \code{NULL} (use \code{colors}), so existing calls are unchanged.} +\item{preset}{optional name of a bundle of publication-grade defaults. The only +value, \code{"publication"}, sets white cell outlines and the colorblind-safe +\code{"RdBu"} palette in one token. It fills only the arguments you did not +supply, so any argument you pass explicitly (e.g. \code{outline.color}, +\code{colors}, \code{palette}) overrides the preset. Defaults to \code{NULL} +(no preset), leaving existing calls unchanged.} + \item{x}{numeric matrix or data frame} \item{...}{other arguments to be passed to the function cor.test.} diff --git a/tests/testthat/_snaps/vdiffr/ggcorrplot-works-preset-publication.svg b/tests/testthat/_snaps/vdiffr/ggcorrplot-works-preset-publication.svg new file mode 100644 index 0000000..055947d --- /dev/null +++ b/tests/testthat/_snaps/vdiffr/ggcorrplot-works-preset-publication.svg @@ -0,0 +1,345 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 +-0.9 +-0.8 +-0.8 +0.7 +-0.9 +0.4 +0.7 +0.6 +0.5 +-0.6 +-0.9 +1 +0.9 +0.8 +-0.7 +0.8 +-0.6 +-0.8 +-0.5 +-0.5 +0.5 +-0.8 +0.9 +1 +0.8 +-0.7 +0.9 +-0.4 +-0.7 +-0.6 +-0.6 +0.4 +-0.8 +0.8 +0.8 +1 +-0.4 +0.7 +-0.7 +-0.7 +-0.2 +-0.1 +0.7 +0.7 +-0.7 +-0.7 +-0.4 +1 +-0.7 +0.1 +0.4 +0.7 +0.7 +-0.1 +-0.9 +0.8 +0.9 +0.7 +-0.7 +1 +-0.2 +-0.6 +-0.7 +-0.6 +0.4 +0.4 +-0.6 +-0.4 +-0.7 +0.1 +-0.2 +1 +0.7 +-0.2 +-0.2 +-0.7 +0.7 +-0.8 +-0.7 +-0.7 +0.4 +-0.6 +0.7 +1 +0.2 +0.2 +-0.6 +0.6 +-0.5 +-0.6 +-0.2 +0.7 +-0.7 +-0.2 +0.2 +1 +0.8 +0.1 +0.5 +-0.5 +-0.6 +-0.1 +0.7 +-0.6 +-0.2 +0.2 +0.8 +1 +0.3 +-0.6 +0.5 +0.4 +0.7 +-0.1 +0.4 +-0.7 +-0.6 +0.1 +0.3 +1 + + +mpg +cyl +disp +hp +drat +wt +qsec +vs +am +gear +carb +mpg +cyl +disp +hp +drat +wt +qsec +vs +am +gear +carb +Corr + + + + + + + + + + + +-1.0 +-0.5 +0.0 +0.5 +1.0 +ggcorrplot works - preset publication + + diff --git a/tests/testthat/test-preset.R b/tests/testthat/test-preset.R new file mode 100644 index 0000000..2678714 --- /dev/null +++ b/tests/testthat/test-preset.R @@ -0,0 +1,50 @@ +# preset = "publication": a one-token bundle of publication-grade defaults (white +# cell outlines + the colorblind-safe RdBu palette). It fills only the arguments +# the caller did NOT supply, so explicit arguments always win, and preset = NULL +# (the default) changes nothing. + +corr <- round(cor(mtcars), 1) +fill <- function(p) ggplot2::ggplot_build(p)$data[[1]]$fill +outline <- function(p) { + i <- which(vapply(p$layers, function(l) class(l$geom)[1], "") %in% c("GeomTile", "GeomPoint"))[1] + p$layers[[i]]$aes_params$colour +} + +test_that("preset = 'publication' sets white outlines and the RdBu palette in one token", { + p <- ggcorrplot(corr, preset = "publication") + expect_identical(outline(p), "white") + expect_equal(fill(p), fill(ggcorrplot(corr, palette = "RdBu", outline.color = "white"))) +}) + +test_that("preset = NULL (the default) leaves every existing call unchanged", { + expect_equal( + ggplot2::ggplot_build(ggcorrplot(corr))$data, + ggplot2::ggplot_build(ggcorrplot(corr, preset = NULL))$data + ) + # the default outline is still gray, not white + expect_identical(outline(ggcorrplot(corr)), "gray") +}) + +test_that("an explicit outline.color overrides the preset", { + expect_identical(outline(ggcorrplot(corr, preset = "publication", outline.color = "black")), "black") +}) + +test_that("an explicit colors overrides the preset palette (colors is not clobbered)", { + # user pins colors -> preset must NOT swap in RdBu + expect_equal( + fill(ggcorrplot(corr, preset = "publication", colors = c("blue", "white", "red"))), + fill(ggcorrplot(corr)) + ) +}) + +test_that("an explicit palette overrides the preset palette", { + expect_equal( + fill(ggcorrplot(corr, preset = "publication", palette = "PuOr")), + fill(ggcorrplot(corr, palette = "PuOr")) + ) +}) + +test_that("an unknown preset errors", { + expect_error(ggcorrplot(corr, preset = "fancy")) + expect_error(ggcorrplot(corr, preset = "Publication")) # match.arg is case-sensitive +}) diff --git a/tests/testthat/test-vdiffr.R b/tests/testthat/test-vdiffr.R index 692af0b..209a902 100644 --- a/tests/testthat/test-vdiffr.R +++ b/tests/testthat/test-vdiffr.R @@ -66,5 +66,11 @@ if (getRversion() >= "4.1") { title = "ggcorrplot works - palette RdBu", fig = ggcorrplot(corr, palette = "RdBu", outline.color = "white", lab = TRUE) ) + + set.seed(123) + vdiffr::expect_doppelganger( + title = "ggcorrplot works - preset publication", + fig = ggcorrplot(corr, preset = "publication", lab = TRUE) + ) }) }