From 65bca19fec11c3401a981f7df2f237245658694e Mon Sep 17 00:00:00 2001 From: Jaron Arbet Date: Fri, 17 Apr 2026 15:28:26 -0700 Subject: [PATCH 1/3] Add rowtitle() function and update roxygen version --- DESCRIPTION | 2 +- NAMESPACE | 1 + R/rowtitle.R | 171 ++++++++++++++++++++++++++++++++++++++++++++++++ man/rowtitle.Rd | 95 +++++++++++++++++++++++++++ 4 files changed, 268 insertions(+), 1 deletion(-) create mode 100644 R/rowtitle.R create mode 100644 man/rowtitle.Rd diff --git a/DESCRIPTION b/DESCRIPTION index aae9bdf..b2f18c6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,7 +29,7 @@ Imports: rlang (>= 1.0.0), cli, farver -RoxygenNote: 7.3.2 +RoxygenNote: 7.3.3 Roxygen: list(markdown = TRUE) URL: https://patchwork.data-imaginist.com, https://github.com/thomasp85/patchwork BugReports: https://github.com/thomasp85/patchwork/issues diff --git a/NAMESPACE b/NAMESPACE index c2f94eb..30f4e4f 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -88,6 +88,7 @@ export(patchworkGrob) export(plot_annotation) export(plot_layout) export(plot_spacer) +export(rowtitle) export(set_dim) export(wrap_elements) export(wrap_ggplot_grob) diff --git a/R/rowtitle.R b/R/rowtitle.R new file mode 100644 index 0000000..e7d97d5 --- /dev/null +++ b/R/rowtitle.R @@ -0,0 +1,171 @@ +#' Create a Row Title for Patchwork +#' +#' Creates a plot with a centered text label designed to be used as a row +#' title in a multi-row patchwork composition. The plot has a minimal theme +#' with a customizable background and bold text. +#' +#' @param label Character string for the row title label. Must be a single value. +#' @param x Numeric x position of text. Must be between 0 and 1. Default: 0.5 (center). +#' @param y Numeric y position of text. Must be between 0 and 1. Default: 0.5 (center). +#' @param size Numeric text size. Must be positive. Default: 5.5. +#' @param hjust Numeric horizontal justification. Must be between 0 and 1. Default: 0.5 (center). +#' @param vjust Numeric vertical justification. Must be between 0 and 1. Default: 0.5 (center). +#' @param fill Character color for plot background. Must be a single value. Default: "grey92". +#' @param color Character color for plot border. Must be a single value. Default: "black". +#' @param linewidth Numeric width of plot border. Must be positive. Default: 1.5. +#' @param margin_top Numeric top margin in points. Must be non-negative. Default: 6. +#' @param margin_right Numeric right margin in points. Must be non-negative. Default: 0. +#' @param margin_bottom Numeric bottom margin in points. Must be non-negative. Default: 0. +#' @param margin_left Numeric left margin in points. Must be non-negative. Default: 0. +#' +#' @return A ggplot object suitable for use in a patchwork composition. +#' +#' @examples +#' ggplot2::theme_set(theme_bw2()) +#' +#' # Create sample plots +#' p1 <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + +#' ggplot2::geom_point() + +#' ggplot2::labs(title = "Plot 1") +#' p2 <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, hp)) + +#' ggplot2::geom_point() + +#' ggplot2::labs(title = "Plot 2") +#' p3 <- ggplot2::ggplot(mtcars, ggplot2::aes(factor(cyl), mpg)) + +#' ggplot2::geom_boxplot() + +#' ggplot2::labs(title = "Plot 3") +#' p4 <- ggplot2::ggplot(mtcars, ggplot2::aes(factor(cyl), hp)) + +#' ggplot2::geom_boxplot() + +#' ggplot2::labs(title = "Plot 4") +#' +#' # Use case 1: Row title as an entire row (spanning all columns) +#' row_title_1 <- rowtitle("Group A") +#' row_title_2 <- rowtitle("Group B") +#' patchwork1 <- p1 + p2 +#' patchwork2 <- p3 + p4 +#' +#' row_title_1 + +#' patchwork1 + +#' row_title_2 + +#' patchwork2 + +#' patchwork::plot_layout(ncol = 1, heights = c(0.2, 1, 0.2, 1)) +#' +#' # Use case 2: Row title as a box to the left (narrow column) +#' row_title_left_1 <- rowtitle("Group\nA") +#' row_title_left_2 <- rowtitle("Group\nB") +#' +#' row_title_left_1 + patchwork1 + +#' row_title_left_2 + patchwork2 + +#' patchwork::plot_layout(ncol = 2, widths = c(0.2, 1)) +#' +#' @export +rowtitle <- function( + label, + x = 0.5, + y = 0.5, + size = 5.5, + hjust = 0.5, + vjust = 0.5, + fill = "grey92", + color = "black", + linewidth = 1.5, + margin_top = 6, + margin_right = 0, + margin_bottom = 0, + margin_left = 0 +) { + # Validate arguments + stopifnot( + is.character(label), + length(label) == 1 + ) + stopifnot( + is.numeric(x), + length(x) == 1, + x >= 0, + x <= 1 + ) + stopifnot( + is.numeric(y), + length(y) == 1, + y >= 0, + y <= 1 + ) + stopifnot( + is.numeric(hjust), + length(hjust) == 1, + hjust >= 0, + hjust <= 1 + ) + stopifnot( + is.numeric(vjust), + length(vjust) == 1, + vjust >= 0, + vjust <= 1 + ) + stopifnot( + is.numeric(size), + length(size) == 1, + size > 0 + ) + stopifnot( + is.numeric(linewidth), + length(linewidth) == 1, + linewidth > 0 + ) + stopifnot( + is.character(fill), + length(fill) == 1 + ) + stopifnot( + is.character(color), + length(color) == 1 + ) + stopifnot( + is.numeric(margin_top), + length(margin_top) == 1, + margin_top >= 0 + ) + stopifnot( + is.numeric(margin_right), + length(margin_right) == 1, + margin_right >= 0 + ) + stopifnot( + is.numeric(margin_bottom), + length(margin_bottom) == 1, + margin_bottom >= 0 + ) + stopifnot( + is.numeric(margin_left), + length(margin_left) == 1, + margin_left >= 0 + ) + + ggplot2::ggplot() + + ggplot2::annotate( + "text", + x = x, + y = y, + label = label, + size = size, + fontface = "bold", + hjust = hjust, + vjust = vjust + ) + + ggplot2::scale_x_continuous(limits = c(0, 1), expand = c(0, 0)) + + ggplot2::scale_y_continuous(limits = c(0, 1), expand = c(0, 0)) + + ggplot2::theme_void() + + ggplot2::theme( + plot.background = ggplot2::element_rect( + fill = fill, + color = color, + linewidth = linewidth + ), + plot.margin = ggplot2::margin( + margin_top, + margin_right, + margin_bottom, + margin_left + ) + ) +} diff --git a/man/rowtitle.Rd b/man/rowtitle.Rd new file mode 100644 index 0000000..5a3b182 --- /dev/null +++ b/man/rowtitle.Rd @@ -0,0 +1,95 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/rowtitle.R +\name{rowtitle} +\alias{rowtitle} +\title{Create a Row Title for Patchwork} +\usage{ +rowtitle( + label, + x = 0.5, + y = 0.5, + size = 5.5, + hjust = 0.5, + vjust = 0.5, + fill = "grey92", + color = "black", + linewidth = 1.5, + margin_top = 6, + margin_right = 0, + margin_bottom = 0, + margin_left = 0 +) +} +\arguments{ +\item{label}{Character string for the row title label. Must be a single value.} + +\item{x}{Numeric x position of text. Must be between 0 and 1. Default: 0.5 (center).} + +\item{y}{Numeric y position of text. Must be between 0 and 1. Default: 0.5 (center).} + +\item{size}{Numeric text size. Must be positive. Default: 5.5.} + +\item{hjust}{Numeric horizontal justification. Must be between 0 and 1. Default: 0.5 (center).} + +\item{vjust}{Numeric vertical justification. Must be between 0 and 1. Default: 0.5 (center).} + +\item{fill}{Character color for plot background. Must be a single value. Default: "grey92".} + +\item{color}{Character color for plot border. Must be a single value. Default: "black".} + +\item{linewidth}{Numeric width of plot border. Must be positive. Default: 1.5.} + +\item{margin_top}{Numeric top margin in points. Must be non-negative. Default: 6.} + +\item{margin_right}{Numeric right margin in points. Must be non-negative. Default: 0.} + +\item{margin_bottom}{Numeric bottom margin in points. Must be non-negative. Default: 0.} + +\item{margin_left}{Numeric left margin in points. Must be non-negative. Default: 0.} +} +\value{ +A ggplot object suitable for use in a patchwork composition. +} +\description{ +Creates a plot with a centered text label designed to be used as a row +title in a multi-row patchwork composition. The plot has a minimal theme +with a customizable background and bold text. +} +\examples{ +ggplot2::theme_set(theme_bw2()) + +# Create sample plots +p1 <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + + ggplot2::geom_point() + + ggplot2::labs(title = "Plot 1") +p2 <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, hp)) + + ggplot2::geom_point() + + ggplot2::labs(title = "Plot 2") +p3 <- ggplot2::ggplot(mtcars, ggplot2::aes(factor(cyl), mpg)) + + ggplot2::geom_boxplot() + + ggplot2::labs(title = "Plot 3") +p4 <- ggplot2::ggplot(mtcars, ggplot2::aes(factor(cyl), hp)) + + ggplot2::geom_boxplot() + + ggplot2::labs(title = "Plot 4") + +# Use case 1: Row title as an entire row (spanning all columns) +row_title_1 <- rowtitle("Group A") +row_title_2 <- rowtitle("Group B") +patchwork1 <- p1 + p2 +patchwork2 <- p3 + p4 + +row_title_1 + + patchwork1 + + row_title_2 + + patchwork2 + + patchwork::plot_layout(ncol = 1, heights = c(0.2, 1, 0.2, 1)) + +# Use case 2: Row title as a box to the left (narrow column) +row_title_left_1 <- rowtitle("Group\nA") +row_title_left_2 <- rowtitle("Group\nB") + +row_title_left_1 + patchwork1 + + row_title_left_2 + patchwork2 + + patchwork::plot_layout(ncol = 2, widths = c(0.2, 1)) + +} From 2ffdc4313f1e04ac0da7c5ef9293f8c6b4aac013 Mon Sep 17 00:00:00 2001 From: Jaron Arbet Date: Fri, 17 Apr 2026 15:32:25 -0700 Subject: [PATCH 2/3] dont update desc --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index b2f18c6..aae9bdf 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,7 +29,7 @@ Imports: rlang (>= 1.0.0), cli, farver -RoxygenNote: 7.3.3 +RoxygenNote: 7.3.2 Roxygen: list(markdown = TRUE) URL: https://patchwork.data-imaginist.com, https://github.com/thomasp85/patchwork BugReports: https://github.com/thomasp85/patchwork/issues From 60f329532d802cd97bb27e89cd766b9601091864 Mon Sep 17 00:00:00 2001 From: Jaron Arbet Date: Fri, 17 Apr 2026 15:33:17 -0700 Subject: [PATCH 3/3] use theme_bw in examples --- R/rowtitle.R | 2 +- man/rowtitle.Rd | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/R/rowtitle.R b/R/rowtitle.R index e7d97d5..84135ee 100644 --- a/R/rowtitle.R +++ b/R/rowtitle.R @@ -21,7 +21,7 @@ #' @return A ggplot object suitable for use in a patchwork composition. #' #' @examples -#' ggplot2::theme_set(theme_bw2()) +#' ggplot2::theme_set(theme_bw()) #' #' # Create sample plots #' p1 <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) + diff --git a/man/rowtitle.Rd b/man/rowtitle.Rd index 5a3b182..b1a81e5 100644 --- a/man/rowtitle.Rd +++ b/man/rowtitle.Rd @@ -56,7 +56,7 @@ title in a multi-row patchwork composition. The plot has a minimal theme with a customizable background and bold text. } \examples{ -ggplot2::theme_set(theme_bw2()) +ggplot2::theme_set(theme_bw()) # Create sample plots p1 <- ggplot2::ggplot(mtcars, ggplot2::aes(wt, mpg)) +