Como criar gráficos com fundo transparente em R usando o ggplot2?

123

Preciso gerar gráficos ggplot2 de arquivos R para PNG com fundo transparente. Tudo está bem com os gráficos R básicos, mas sem transparência com o 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()

Existe alguma maneira de obter um fundo transparente com o ggplot2?

Yuriy Petrovskiy
fonte
3
Veja também esta resposta , a solução atual é adicionartheme(panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA))
Paul Rougieux
Por favor, considere marcar a segunda resposta (por YRC) como aceita devido a obsoletos 'opts'.
Davit Sargsyan

Respostas:

70

Atualizado com a theme()função ggsave()e o código para o fundo da legenda:

df <- data.frame(y = d, x = 1, 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
  ) 

A maneira mais rápida é usar using rect, pois todos os elementos retangulares herdam de rect:

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

Maneira mais controlada é usar opções de theme:

p <- p +
  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
  )
p

Para salvar (este último passo é importante):

ggsave(p, filename = "tr_tst2.png",  bg = "transparent")
YCR
fonte
1
Se você não definir a plot.backgroundcor como a resposta acima, sua plotagem terá um contorno fraco.
jsta
87

Há também uma plot.backgroundopção além de 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()

Por algum motivo, a imagem carregada está sendo exibida de maneira diferente da do meu computador, então eu a omiti. Mas para mim, recebo um gráfico com um fundo totalmente cinza, exceto pela parte da caixa do gráfico de caixa que ainda é branca. Isso também pode ser alterado usando a estética de preenchimento no geom boxplot, acredito.

Editar

O ggplot2 foi atualizado e a opts()função foi preterida. Atualmente, você usaria em theme()vez de opts()e em element_rect()vez de theme_rect()etc.

joran
fonte
Eu não esperava que ele funcionasse com um Mac quando testado com o PowerPoint atual dessa plataforma, mas funciona como anunciado. E também funciona com pdf se você remover as unidades e substituir tamanhos em polegadas Bom trabalho.
IRTFM 17/09/11
1
Isso funciona muito bem com o MS Powerpoint 2010. Na verdade, eu precisava disso para esse fim.
Yuriy Petrovskiy
13
Se você estiver usando o ggsave, não se esqueça de adicionar bg = "transparent"para passar para o dispositivo gráfico png.
Tom
12
se você estiver usando o knitrpacote (ou slidifyetc), precisará passar dev.args = list(bg = 'transparent')como uma opção de chunk. Mais detalhes aqui stackoverflow.com/a/13826154/561698
Andrew
3

Apenas para melhorar a resposta do YCR:

1) Adicionei linhas pretas nos eixos xey. Caso contrário, eles também serão transparentes.

2) Adicionei um tema transparente à legenda. Caso contrário, você receberá um preenchimento lá, o que não será muito estético.

Por fim, observe que todos trabalham apenas com os formatos pdf e png. JPEG falha ao produzir gráficos transparentes.

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
)
Rtist
fonte