From 41fe2b61709b88a762725a09e3174e03c79fdddf Mon Sep 17 00:00:00 2001 From: Jared Knowles Date: Tue, 19 May 2026 22:12:03 -0600 Subject: [PATCH] fix: use full-bleed background rect instead of opaque logo grob The previous fix applied the plot's background to the logo grob directly, which made it opaque and covered caption/axis text that overlaps into the logo area via negative margins. Instead, wrap the entire arrangeGrob composition in a grobTree with a background rectGrob behind it. This fills transparent areas (logo strip, padding gaps) with the plot's background color while keeping the logo grob itself transparent so overlapping text remains visible. --- R/logo.R | 45 ++++++++++++++++++++++++++------------------- 1 file changed, 26 insertions(+), 19 deletions(-) diff --git a/R/logo.R b/R/logo.R index 70a090e..11b44c8 100644 --- a/R/logo.R +++ b/R/logo.R @@ -64,15 +64,10 @@ add_logo <- function(plot, logo, margin_param = NULL, font_scale = 1.1, position <- match.arg(position) at_top <- grepl("top", position) - # Inherit the plot's background color so the logo strip matches. - # make_logo_grob() uses theme_void() (transparent), so without this the - # logo area falls back to the device default (white). + # Capture the plot's background color so we can fill the entire composed + # grob with it. The logo grob must stay transparent (theme_void) so that + # caption/axis text overlapping via negative margins remains visible. bg_fill <- plot$theme$plot.background$fill - if (!is.null(bg_fill) && !is.na(bg_fill)) { - logo <- logo + ggplot2::theme( - plot.background = ggplot2::element_rect(fill = bg_fill, color = NA) - ) - } # Inflate text sizes to compensate for arrangeGrob viewport shrinkage. # All theme text elements use rel() sizing, so scaling the root 'text' @@ -91,8 +86,8 @@ add_logo <- function(plot, logo, margin_param = NULL, font_scale = 1.1, } else { plot <- plot + theme(plot.margin = unit(c(-14, 7, 7, 7), "pt")) } - arrangeGrob(logo, plot, heights = c(0.1, 0.93), - padding = unit(0.1, "line")) + composed <- arrangeGrob(logo, plot, heights = c(0.1, 0.93), + padding = unit(0.1, "line")) } else { # Bottom placement (original behaviour) if(has_caption(plot)) { @@ -105,8 +100,18 @@ add_logo <- function(plot, logo, margin_param = NULL, font_scale = 1.1, } else { plot <- plot + theme(plot.margin = unit(c(7, 7, -14, 7), "pt")) } - arrangeGrob(plot, logo, heights = c(0.93, 0.1), - padding = unit(0.1, "line")) + composed <- arrangeGrob(plot, logo, heights = c(0.93, 0.1), + padding = unit(0.1, "line")) + } + + # Wrap with a full-bleed background rect so any transparent areas (the + # logo strip, padding gaps) pick up the plot's background color instead + # of the device default (white). + if (!is.null(bg_fill) && !is.na(bg_fill)) { + bg_rect <- grid::rectGrob(gp = grid::gpar(fill = bg_fill, col = NA)) + grid::grobTree(bg_rect, composed) + } else { + composed } } @@ -174,13 +179,8 @@ has_caption <- function(gg) { #' } add_logo_ga <- function(plot_list, logo, nrow = 1, widths = NULL, margin_param = NULL, font_scale = 1.1) { - # Inherit the background color from the first plot so the logo strip matches + # Capture the background color from the first plot bg_fill <- plot_list[[1]]$theme$plot.background$fill - if (!is.null(bg_fill) && !is.na(bg_fill)) { - logo <- logo + ggplot2::theme( - plot.background = ggplot2::element_rect(fill = bg_fill, color = NA) - ) - } # Inflate text sizes to compensate for viewport shrinkage if (!is.null(font_scale) && font_scale != 1) { @@ -215,7 +215,14 @@ add_logo_ga <- function(plot_list, logo, nrow = 1, widths = NULL, hold <- arrangeGrob(grobs = plot_list, nrow = 1, ncol = length(plot_list), widths = widths) } - arrangeGrob(hold, logo, heights = c(0.93, .07)) + composed <- arrangeGrob(hold, logo, heights = c(0.93, .07)) + + if (!is.null(bg_fill) && !is.na(bg_fill)) { + bg_rect <- grid::rectGrob(gp = grid::gpar(fill = bg_fill, col = NA)) + grid::grobTree(bg_rect, composed) + } else { + composed + } }