How to make graphics with transparent background in R using ggplot2?

129,639

Solution 1

Create the initial plot:

library(ggplot2)
d <- rnorm(100)
df <- data.frame(
  x = 1,
  y = d,
  group = rep(c("gr1", "gr2"), 50)
)
p <- ggplot(df) + stat_boxplot(
  aes(
    x = x,
    y = y,
    color = group
  ), 
  fill = "transparent" # for the inside of the boxplot
)

The fastest way to modify the plot above to have a completely transparent background is to set theme()'s rect argument, as all the rectangle elements inherit from rect:

p <- p + theme(rect = element_rect(fill = "transparent"))
          
p

A more controlled way is to set theme()'s more specific arguments individually:

p <- p + theme(
  panel.background = element_rect(fill = "transparent",
                                  colour = NA_character_), # necessary to avoid drawing panel outline
  panel.grid.major = element_blank(), # get rid of major grid
  panel.grid.minor = element_blank(), # get rid of minor grid
  plot.background = element_rect(fill = "transparent",
                                 colour = NA_character_), # necessary to avoid drawing plot outline
  legend.background = element_rect(fill = "transparent"),
  legend.box.background = element_rect(fill = "transparent"),
  legend.key = element_rect(fill = "transparent")
)

p

ggsave() offers a dedicated argument bg to set the

Background colour. If NULL, uses the plot.background fill value from the plot theme.

To write a ggplot object p to filename on disk using a transparent background:

ggsave(
  plot = p,
  filename = "tr_tst2.png",
  bg = "transparent"
)

Solution 2

There is also a plot.background option in addition to panel.background:

df <- data.frame(y=d,x=1)
p <- ggplot(df) + stat_boxplot(aes(x = x,y=y)) 
p <- p + opts(
    panel.background = theme_rect(fill = "transparent",colour = NA), # or theme_blank()
    panel.grid.minor = theme_blank(), 
    panel.grid.major = theme_blank(),
    plot.background = theme_rect(fill = "transparent",colour = NA)
)
#returns white background
png('tr_tst2.png',width=300,height=300,units="px",bg = "transparent")
print(p)
dev.off()

For some reason, the uploaded image is displaying differently than on my computer, so I've omitted it. But for me, I get a plot with an entirely gray background except for the box part of the boxplot which is still white. That can be changed using the fill aesthetic in the boxplot geom as well, I believe.

Edit

ggplot2 has since been updated and the opts() function has been deprecated. Currently, you would use theme() instead of opts() and element_rect() instead of theme_rect(), etc.

Solution 3

Just to improve YCR's answer:

1) I added black lines on x and y axis. Otherwise they are made transparent too.

2) I added a transparent theme to the legend key. Otherwise, you will get a fill there, which won't be very esthetic.

Finally, note that all those work only with pdf and png formats. jpeg fails to produce transparent graphs.

MyTheme_transparent <- theme(
    panel.background = element_rect(fill = "transparent"), # bg of the panel
    plot.background = element_rect(fill = "transparent", color = NA), # bg of the plot
    panel.grid.major = element_blank(), # get rid of major grid
    panel.grid.minor = element_blank(), # get rid of minor grid
    legend.background = element_rect(fill = "transparent"), # get rid of legend bg
    legend.box.background = element_rect(fill = "transparent"), # get rid of legend panel bg
    legend.key = element_rect(fill = "transparent", colour = NA), # get rid of key legend fill, and of the surrounding
    axis.line = element_line(colour = "black") # adding a black line for x and y axis
)
Share:
129,639
Yuriy Petrovskiy
Author by

Yuriy Petrovskiy

Updated on December 10, 2021

Comments

  • Yuriy Petrovskiy
    Yuriy Petrovskiy over 2 years

    I need to output ggplot2 graphics from R to PNG files with transparent background. Everything is ok with basic R graphics, but no transparency with ggplot2:

    d <- rnorm(100) #generating random data
    
    #this returns transparent png
    png('tr_tst1.png',width=300,height=300,units="px",bg = "transparent")
    boxplot(d)
    dev.off()
    
    df <- data.frame(y=d,x=1)
    p <- ggplot(df) + stat_boxplot(aes(x = x,y=y)) 
    p <- p + opts(
        panel.background = theme_rect(fill = "transparent",colour = NA), # or theme_blank()
        panel.grid.minor = theme_blank(), 
        panel.grid.major = theme_blank()
    )
    #returns white background
    png('tr_tst2.png',width=300,height=300,units="px",bg = "transparent")
    p
    dev.off()
    

    Is there any way to get transparent background with ggplot2?

    • Paul Rougieux
      Paul Rougieux over 7 years
      See also this answer, the current solution is to add theme(panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA))
    • Davit Sargsyan
      Davit Sargsyan about 6 years
      Please consider marking the second answer (by YRC) as accepted due to 'opts' being obsolete.
  • IRTFM
    IRTFM over 12 years
    I wasn't expecting it to work with a Mac when tested with that platform's current PowerPoint but it works as advertised. And it works with pdf's as well if you remove the units and substitute sizes in inches Good job.
  • Yuriy Petrovskiy
    Yuriy Petrovskiy over 12 years
    This works excellent with MS Powerpoint 2010. Actually, I needed it right for this purpose.
  • Tom
    Tom about 12 years
    If you're using ggsave, don't forget to add in bg = "transparent" to pass to the png graphics device.
  • Andrew
    Andrew about 10 years
    if you're using the knitr package (or slidify etc) you need to pass dev.args = list(bg = 'transparent') as a chunk option. More detail here stackoverflow.com/a/13826154/561698
  • jsta
    jsta about 6 years
    If you don't set the plot.background color like the answer above your plot will have a faint outline.
  • John T
    John T over 3 years
    Ahhh... spent too much time on not knowing last step. Saving file with , bg = "transparent".
  • Gregor Thomas
    Gregor Thomas over 3 years
    theme_bw gives a white background, not a transparent background.
  • Jimmy Carter
    Jimmy Carter over 2 years
    I cannot believe in 2022 that ggsave is in inches and not pixels.
  • Salim B
    Salim B almost 2 years
    @jsta It's not plot.background but panel.background where you need to set colour = NA.
  • Salim B
    Salim B almost 2 years
    Addendum: My mistake, it needs to be set on both.