Yuriy Petrovskiy
Yuriy Petrovskiy

Reputation: 8178

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

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?

Upvotes: 164

Views: 163120

Answers (6)

Sara
Sara

Reputation: 93

The Cairo package can be used to save ggplots as images with transparent backgrounds. https://cran.r-project.org/web/packages/Cairo/Cairo.pdf

CairoPNG(filename = "TEST.png", bg = "transparent")

ggplot(mtcars, aes(wt, mpg))+
   geom_point()+
   theme(panel.background = element_rect(fill = "transparent"),
      plot.background = element_rect(fill = "transparent", colour = NA))

dev.off()

Upvotes: 1

YCR
YCR

Reputation: 4002

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"
)

Upvotes: 119

mvanaman
mvanaman

Reputation: 333

I believe this will work for those who are working within R Markdown and don't want to use ggsave to save a separate file.

You do the following, and just add this chunk option: {r, dev.args = list(bg = 'transparent')}:

ggplot(mtcars, aes(wt, mpg)) +
   geom_point() +
   theme(
     # makes background transparent:
     plot.background = element_rect(fill = "transparent",colour = NA),
     # gets rid of white border around plot: 
     panel.border = element_blank() 
   )

For example, I am using ioslides presentation within R Markdown, though note that I have not tested this outside of this context.

Upvotes: 0

Qinsi
Qinsi

Reputation: 820

As for someone don't like gray background like academic editor, try this:

p <- p + theme_bw()
p

Upvotes: 0

Rtist
Rtist

Reputation: 4205

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
)

Upvotes: 6

joran
joran

Reputation: 173577

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.

Upvotes: 93

Related Questions