如何使用ggplot2在R中制作带有透明背景的图形?

161

我需要将R中的ggplot2图形输出为带有透明背景的PNG文件。基本的R图形没有问题,但是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()

有没有办法在ggplot2中获得透明背景?


6
请参考这个答案,目前的解决方案是添加theme(panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA)) - Paul Rougieux
请考虑将第二个答案(由YRC提供)标记为已接受,因为“opts”已经过时。 - Davit Sargsyan
6个回答

113
创建初始图表:
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
)

将上面的图表修改为完全透明的背景的最快方法是设置theme()rect参数,因为所有矩形元素都继承自rect
p <- p + theme(rect = element_rect(fill = "transparent"))
          
p

更加可控的方法是单独设置theme()的更具体参数:

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()提供了一个专用的参数bg来设置背景颜色。如果为NULL,则使用绘图主题中的plot.background填充值。

要将ggplot对象p写入磁盘上的filename并使用透明背景,请使用以下方法:

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

2
如果您不像上面的答案设置plot.background颜色,则您的图表将有一个模糊的轮廓。 - jsta
1
啊啊啊...浪费太多时间在不知道最后一步上。使用, bg = "transparent" 保存文件。 - John T
我简直无法相信在2022年,ggsave仍然使用英寸而不是像素。 - Jimmy Carter
@jsta,你需要设置colour = NA的地方不是plot.background而是**panel.background**。 - Salim B
补充说明:我的错误,它需要在两个上设置。 - Salim B

93

除了panel.background选项之外,还有一个plot.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()
由于某种原因,上传的图像显示方式与我的电脑上不同,因此我已省略它。但对于我来说,我得到的是一个完全灰色背景的图表,除了盒形图的框部分仍然是白色的。我认为可以在boxplot中使用fill美学来改变它。

编辑

ggplot2已经更新,opts()函数已弃用。目前,您应该使用theme()代替opts(),使用element_rect()代替theme_rect()等。


当我测试这个程序时,我没有想到它能在Mac上运行,但是它按照广告所说的那样工作了。如果你移除单位并以英寸代替尺寸,它也适用于pdf文件。做得好。 - IRTFM
1
这在 MS Powerpoint 2010 上运行得非常好。实际上,我正需要它来完成这个目的。 - Yuriy Petrovskiy
16
如果你正在使用 ggsave,不要忘记添加 bg = "transparent" 以传递给 png 图形设备。 - Tom
15
如果您正在使用 knitr 包(或者 slidify 等),您需要将 dev.args = list(bg = 'transparent') 作为代码块选项传递。更多细节请参见此处:https://dev59.com/p2vXa4cB1Zd3GeqPOO3g#13826154。 - Andrew

6

只是为了改进YCR的回答:

1)我在x和y轴上加了黑线。否则它们会透明。

2)我在图例键中添加了一个透明主题。否则,您将在那里得到一个填充,这不太美观。

最后,请注意所有这些只适用于pdf和png格式。jpeg无法生成透明图形。

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
)

1

Cairo包可以用于将ggplots保存为具有透明背景的图像。 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()

请注意"CaiorPNG"上的错别字(r位置不正确)。 - Denis Cousineau

0

对于不喜欢像学术编辑器那样的灰色背景的人,可以尝试这个:

p <- p + theme_bw()
p

3
theme_bw 提供了一个白色背景,而不是透明背景。 - Gregor Thomas

0

我相信这对于那些在R Markdown中工作且不想使用ggsave保存单独文件的人来说是有效的。

你只需要按照以下步骤,并添加此代码块选项:{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() 
   )

例如,我正在使用R Markdown中的ioslides演示文稿,但请注意我尚未在此上下文之外进行过测试。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接