Home > Back-end >  R ggbreak have non-transparent background
R ggbreak have non-transparent background

Time:08-24

I am generating a plot with ggbreak; however, it seems that the background is no longer transparent even if I adapt the theme to have panel and background be transparent. Is there a way around this?

Minimum working example

library(ggplot2)
library(ggbreak)

set.seed(2022-08-23)
d <- data.frame(x = 1:20,
   y = c(rnorm(5)   4, rnorm(5)   20, rnorm(5)   5, rnorm(5)   22))
 
plt1 <- ggplot(d, aes(y, x))   geom_col(orientation="y")   
    theme(panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(), 
          panel.background = element_rect(fill = "transparent", colour = NA), 
          plot.background = element_rect(fill = "transparent",  colour = NA)
  )

ggsave(plt1, filename = "test1.png", device = 'png', bg = 'transparent')

plt2 <- ggplot(d, aes(y, x))   geom_col(orientation="y")   
    theme(panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(), 
          panel.background = element_rect(fill = "transparent", colour = NA), 
          plot.background = element_rect(fill = "transparent",  colour = NA)
  )   scale_x_break(c(7, 17), scales = 1.5)
ggsave(plt2, filename = "test2.png", device = 'png', bg = 'transparent')

the file test1.png is indeed with a transparen background, but not test2.png.

CodePudding user response:

It turns out that ggbreak works via ggplotify. What this means is that the existing plot is actually built into a grob table of 2 or more panels and this complex grob tree is used as an annotation layer of a new ggplot object. Unfortunately, this means the resulting object breaks the normal expectations of ggplot. En route, it picks up solid backgrounds which are opaque rectGrob objects.

This means that there may be no easy way to get a transparent background with ggbreak. It is possible to make the background transparent, but it requires a bit of grob-hacking:

library(ggplot2)
library(ggbreak)

set.seed(2022-08-23)
d <- data.frame(x = 1:20,
   y = c(rnorm(5)   4, rnorm(5)   20, rnorm(5)   5, rnorm(5)   22))


plt2 <- ggplot(d, aes(y, x))   geom_col(orientation="y")   
    theme(panel.grid.major = element_blank(), 
          panel.grid.minor = element_blank(), 
          panel.background = element_rect(fill = "transparent", colour = NA), 
          plot.background = element_blank()
  )   scale_x_break(c(7, 17), scales = 1.5)

plt3 <- ggplotify::as.ggplot(grid::grid.draw(plt2, recording = FALSE))

grobs <- plt3$layers[[2]]$geom_params$grob 
grobs$grobs[[1]] <- zeroGrob()
groblets <- grobs$grobs[[6]]$children
groblets[[1]] <- zeroGrob()
groblets[[4]]$grobs[[37]] <- zeroGrob()
groblets -> grobs$grobs[[6]]$children
grobs -> plt3$layers[[2]]$geom_params$grob 

ggsave(plt3, filename = "test2.png", device = 'png', bg = 'transparent')

Here is the result overlaid on text in a word processor:

enter image description here

CodePudding user response:

It seems that ggbreak is using the default theme while re-building the plot with breaks. So a work-around is to make the default theme transparant:

# modify the default theme 
old_theme <- theme_get()
theme_update(panel.grid.major = element_blank(), 
        panel.grid.minor = element_blank(), 
        panel.background = element_rect(fill = "transparent", colour = NA), 
        plot.background = element_blank()
)

plt3 <- ggplot(d, aes(y, x))   geom_col(orientation="y")   scale_x_break(c(7, 17), scales = 1.5)
ggsave(plt3, filename = "test3.png",  device = 'png', bg = 'transparent')

# restore the theme
theme_set(old_theme )
  • Related