From e1e432a1d47ea52a3f39fbe92105f5c5c6612eaf Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 2 Jun 2025 16:03:03 +0200 Subject: [PATCH 1/5] add panel settings --- R/theme-sub.R | 3 ++- man/subtheme.Rd | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/R/theme-sub.R b/R/theme-sub.R index abfb178c44..c1d34f2b49 100644 --- a/R/theme-sub.R +++ b/R/theme-sub.R @@ -105,7 +105,8 @@ theme_sub_legend <- function(background, margin, spacing, spacing.x, spacing.y, #' @export #' @describeIn subtheme Theme specification for the panels. -theme_sub_panel <- function(background, border, spacing, spacing.x, spacing.y, +theme_sub_panel <- function(background, border, + widths, heights, spacing, spacing.x, spacing.y, grid, grid.major, grid.minor, grid.major.x, grid.major.y, grid.minor.x, grid.minor.y, ontop) { subtheme(find_args(), "panel.") diff --git a/man/subtheme.Rd b/man/subtheme.Rd index a05a98a54c..bb9870b595 100644 --- a/man/subtheme.Rd +++ b/man/subtheme.Rd @@ -54,6 +54,8 @@ theme_sub_legend( theme_sub_panel( background, border, + widths, + heights, spacing, spacing.x, spacing.y, From 895dd2f3d3bea21299e11baa95ded57510f7ef1a Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Mon, 2 Jun 2025 16:03:14 +0200 Subject: [PATCH 2/5] add minor ticks settings --- R/theme-sub.R | 14 +++++++------- man/subtheme.Rd | 48 ++++++++++++++++++++++++++++++++++++++++-------- 2 files changed, 47 insertions(+), 15 deletions(-) diff --git a/R/theme-sub.R b/R/theme-sub.R index c1d34f2b49..c32edb3f52 100644 --- a/R/theme-sub.R +++ b/R/theme-sub.R @@ -54,43 +54,43 @@ subtheme <- function(elements, prefix = "", suffix = "", call = caller_env()) { #' @export #' @describeIn subtheme Theme specification for all axes. -theme_sub_axis <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis <- function(title, text, ticks, ticks.length, line, minor.ticks.length) { subtheme(find_args(), "axis.") } #' @export #' @describeIn subtheme Theme specification for both x axes. -theme_sub_axis_x <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis_x <- function(title, text, ticks, ticks.length, line, minor.ticks.length) { subtheme(find_args(), "axis.", ".x") } #' @export #' @describeIn subtheme Theme specification for both y axes. -theme_sub_axis_y <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis_y <- function(title, text, ticks, ticks.length, line, minor.ticks.length) { subtheme(find_args(), "axis.", ".y") } #' @export #' @describeIn subtheme Theme specification for the bottom x axis. -theme_sub_axis_bottom <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis_bottom <- function(title, text, ticks, ticks.length, line, minor.ticks, minor.ticks.length) { subtheme(find_args(), "axis.", ".x.bottom") } #' @export #' @describeIn subtheme Theme specification for the top x axis. -theme_sub_axis_top <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis_top <- function(title, text, ticks, ticks.length, line, minor.ticks, minor.ticks.length) { subtheme(find_args(), "axis.", ".x.top") } #' @export #' @describeIn subtheme Theme specification for the left y axis. -theme_sub_axis_left <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis_left <- function(title, text, ticks, ticks.length, line, minor.ticks, minor.ticks.length) { subtheme(find_args(), "axis.", ".y.left") } #' @export #' @describeIn subtheme Theme specification for the right y axis. -theme_sub_axis_right <- function(title, text, ticks, ticks.length, line) { +theme_sub_axis_right <- function(title, text, ticks, ticks.length, line, minor.ticks, minor.ticks.length) { subtheme(find_args(), "axis.", ".y.right") } diff --git a/man/subtheme.Rd b/man/subtheme.Rd index bb9870b595..6441e33076 100644 --- a/man/subtheme.Rd +++ b/man/subtheme.Rd @@ -15,19 +15,51 @@ \alias{theme_sub_strip} \title{Shortcuts for theme settings} \usage{ -theme_sub_axis(title, text, ticks, ticks.length, line) +theme_sub_axis(title, text, ticks, ticks.length, line, minor.ticks.length) -theme_sub_axis_x(title, text, ticks, ticks.length, line) +theme_sub_axis_x(title, text, ticks, ticks.length, line, minor.ticks.length) -theme_sub_axis_y(title, text, ticks, ticks.length, line) +theme_sub_axis_y(title, text, ticks, ticks.length, line, minor.ticks.length) -theme_sub_axis_bottom(title, text, ticks, ticks.length, line) +theme_sub_axis_bottom( + title, + text, + ticks, + ticks.length, + line, + minor.ticks, + minor.ticks.length +) -theme_sub_axis_top(title, text, ticks, ticks.length, line) +theme_sub_axis_top( + title, + text, + ticks, + ticks.length, + line, + minor.ticks, + minor.ticks.length +) -theme_sub_axis_left(title, text, ticks, ticks.length, line) +theme_sub_axis_left( + title, + text, + ticks, + ticks.length, + line, + minor.ticks, + minor.ticks.length +) -theme_sub_axis_right(title, text, ticks, ticks.length, line) +theme_sub_axis_right( + title, + text, + ticks, + ticks.length, + line, + minor.ticks, + minor.ticks.length +) theme_sub_legend( background, @@ -100,7 +132,7 @@ theme_sub_strip( ) } \arguments{ -\item{background, background.x, background.y, border, box, box.background, box.just, box.margin, box.spacing, caption, caption.position, clip, direction, grid, grid.major, grid.major.x, grid.major.y, grid.minor, grid.minor.x, grid.minor.y, justification, key, key.height, key.size, key.width, line, margin, ontop, placement, position, spacing, spacing.x, spacing.y, subtitle, switch.pad.grid, switch.pad.wrap, tag, tag.location, tag.position, text, text.x, text.x.bottom, text.x.top, text.y, text.y.left, text.y.right, ticks, ticks.length, title, title.position}{Arguments that are renamed and passed on to \code{\link[=theme]{theme()}}.} +\item{background, background.x, background.y, border, box, box.background, box.just, box.margin, box.spacing, caption, caption.position, clip, direction, grid, grid.major, grid.major.x, grid.major.y, grid.minor, grid.minor.x, grid.minor.y, heights, justification, key, key.height, key.size, key.width, line, margin, minor.ticks, minor.ticks.length, ontop, placement, position, spacing, spacing.x, spacing.y, subtitle, switch.pad.grid, switch.pad.wrap, tag, tag.location, tag.position, text, text.x, text.x.bottom, text.x.top, text.y, text.y.left, text.y.right, ticks, ticks.length, title, title.position, widths}{Arguments that are renamed and passed on to \code{\link[=theme]{theme()}}.} } \value{ A \code{theme}-class object that can be added to a plot. From 0269b0f7f00c9533bb55f488834617dda688eb05 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 3 Jun 2025 09:40:10 +0200 Subject: [PATCH 3/5] add test for covering theme_sub items --- tests/testthat/test-theme.R | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/testthat/test-theme.R b/tests/testthat/test-theme.R index 9b68ae2b09..6e26d9f6bc 100644 --- a/tests/testthat/test-theme.R +++ b/tests/testthat/test-theme.R @@ -736,6 +736,28 @@ test_that("geom elements are inherited correctly", { expect_equal(p$colour, "red") }) +test_that("theme elements are covered in `theme_sub_*()` functions", { + # We use a snapshot test here to trigger when a new theme element is added + # or removed. + # A failure of this test should be taken as a prompt to see if the new + # theme element should be included in one of the `theme_sub_*` functions. + + fmls <- paste0("axis.", fn_fmls_names(theme_sub_axis)) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_x), ".x")) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_y), ".y")) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_top), ".x.top")) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_bottom), ".x.bottom")) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_left), ".y.left")) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_right), ".y.right") ) + fmls <- c(fmls, paste0("legend.", fn_fmls_names(theme_sub_legend))) + fmls <- c(fmls, paste0("plot.", fn_fmls_names(theme_sub_plot))) + fmls <- c(fmls, paste0("panel.", fn_fmls_names(theme_sub_panel))) + fmls <- c(fmls, paste0("strip.", fn_fmls_names(theme_sub_strip))) + + extra_elements <- setdiff(fn_fmls_names(theme), fmls) + expect_snapshot(extra_elements) +}) + # Visual tests ------------------------------------------------------------ test_that("element_polygon() can render a grob", { From c21d39f51f3cd91b303f78dcfc97177efaea120d Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 3 Jun 2025 09:58:25 +0200 Subject: [PATCH 4/5] add new arguments --- R/theme-sub.R | 22 ++++++++++++++++++---- man/subtheme.Rd | 26 ++++++++++++++++++++++---- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/R/theme-sub.R b/R/theme-sub.R index c32edb3f52..72a60ebf72 100644 --- a/R/theme-sub.R +++ b/R/theme-sub.R @@ -96,10 +96,24 @@ theme_sub_axis_right <- function(title, text, ticks, ticks.length, line, minor.t #' @export #' @describeIn subtheme Theme specification for the legend. -theme_sub_legend <- function(background, margin, spacing, spacing.x, spacing.y, - key, key.size, key.height, key.width, text, title, - position, direction, justification, box, box.just, - box.margin, box.background, box.spacing) { +theme_sub_legend <- function( + # Text stuff + text, text.position, title, title.position, + # Drawn elements + background, frame, ticks, ticks.length, axis.line, + # Spacings + spacing, spacing.x, spacing.y, margin, + # Seys + key, key.size, key.height, key.width, key.spacing, key.spacing.x, + key.spacing.y, key.justification, + # Settings + byrow, position, direction, location, position.inside, + # Justification + justification, justification.top, justification.bottom, justification.left, + justification.right, justification.inside, + # Box + box, box.just, box.margin, box.background, box.spacing +) { subtheme(find_args(), "legend.") } diff --git a/man/subtheme.Rd b/man/subtheme.Rd index 6441e33076..c79c5b1e25 100644 --- a/man/subtheme.Rd +++ b/man/subtheme.Rd @@ -62,20 +62,38 @@ theme_sub_axis_right( ) theme_sub_legend( + text, + text.position, + title, + title.position, background, - margin, + frame, + ticks, + ticks.length, + axis.line, spacing, spacing.x, spacing.y, + margin, key, key.size, key.height, key.width, - text, - title, + key.spacing, + key.spacing.x, + key.spacing.y, + key.justification, + byrow, position, direction, + location, + position.inside, justification, + justification.top, + justification.bottom, + justification.left, + justification.right, + justification.inside, box, box.just, box.margin, @@ -132,7 +150,7 @@ theme_sub_strip( ) } \arguments{ -\item{background, background.x, background.y, border, box, box.background, box.just, box.margin, box.spacing, caption, caption.position, clip, direction, grid, grid.major, grid.major.x, grid.major.y, grid.minor, grid.minor.x, grid.minor.y, heights, justification, key, key.height, key.size, key.width, line, margin, minor.ticks, minor.ticks.length, ontop, placement, position, spacing, spacing.x, spacing.y, subtitle, switch.pad.grid, switch.pad.wrap, tag, tag.location, tag.position, text, text.x, text.x.bottom, text.x.top, text.y, text.y.left, text.y.right, ticks, ticks.length, title, title.position, widths}{Arguments that are renamed and passed on to \code{\link[=theme]{theme()}}.} +\item{axis.line, background, background.x, background.y, border, box, box.background, box.just, box.margin, box.spacing, byrow, caption, caption.position, clip, direction, frame, grid, grid.major, grid.major.x, grid.major.y, grid.minor, grid.minor.x, grid.minor.y, heights, justification, justification.bottom, justification.inside, justification.left, justification.right, justification.top, key, key.height, key.justification, key.size, key.spacing, key.spacing.x, key.spacing.y, key.width, line, location, margin, minor.ticks, minor.ticks.length, ontop, placement, position, position.inside, spacing, spacing.x, spacing.y, subtitle, switch.pad.grid, switch.pad.wrap, tag, tag.location, tag.position, text, text.position, text.x, text.x.bottom, text.x.top, text.y, text.y.left, text.y.right, ticks, ticks.length, title, title.position, widths}{Arguments that are renamed and passed on to \code{\link[=theme]{theme()}}.} } \value{ A \code{theme}-class object that can be added to a plot. From ee641dda5ffdafcb412e97813a006786e389e971 Mon Sep 17 00:00:00 2001 From: Teun van den Brand Date: Tue, 3 Jun 2025 09:58:39 +0200 Subject: [PATCH 5/5] accept snapshot --- tests/testthat/_snaps/theme.md | 19 +++++++++++++++++++ tests/testthat/test-theme.R | 2 +- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/tests/testthat/_snaps/theme.md b/tests/testthat/_snaps/theme.md index 0218bbef51..8a2f231479 100644 --- a/tests/testthat/_snaps/theme.md +++ b/tests/testthat/_snaps/theme.md @@ -103,3 +103,22 @@ The `options('ggplot2.discrete.colour')` setting is incompatible with the `palette.colour.discrete` theme setting. i You can set `options(ggplot2.discrete.colour = NULL)`. +# theme elements are covered in `theme_sub_*()` functions + + Code + extra_elements + Output + [1] "..." "line" + [3] "rect" "text" + [5] "title" "point" + [7] "polygon" "geom" + [9] "spacing" "margins" + [11] "aspect.ratio" "axis.text.theta" + [13] "axis.text.r" "axis.ticks.theta" + [15] "axis.ticks.r" "axis.minor.ticks.theta" + [17] "axis.minor.ticks.r" "axis.ticks.length.theta" + [19] "axis.ticks.length.r" "axis.minor.ticks.length.theta" + [21] "axis.minor.ticks.length.r" "axis.line.theta" + [23] "axis.line.r" "complete" + [25] "validate" + diff --git a/tests/testthat/test-theme.R b/tests/testthat/test-theme.R index 6e26d9f6bc..e1c80df7a8 100644 --- a/tests/testthat/test-theme.R +++ b/tests/testthat/test-theme.R @@ -748,7 +748,7 @@ test_that("theme elements are covered in `theme_sub_*()` functions", { fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_top), ".x.top")) fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_bottom), ".x.bottom")) fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_left), ".y.left")) - fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_right), ".y.right") ) + fmls <- c(fmls, paste0("axis.", fn_fmls_names(theme_sub_axis_right), ".y.right")) fmls <- c(fmls, paste0("legend.", fn_fmls_names(theme_sub_legend))) fmls <- c(fmls, paste0("plot.", fn_fmls_names(theme_sub_plot))) fmls <- c(fmls, paste0("panel.", fn_fmls_names(theme_sub_panel)))