¿Cómo hacer gráficos con fondo transparente en R usando ggplot2?

123

Necesito generar gráficos ggplot2 de archivos R a PNG con fondo transparente. Todo está bien con gráficos R básicos, pero no hay transparencia con 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()

¿Hay alguna forma de obtener un fondo transparente con ggplot2?

Yuriy Petrovskiy
fuente
3
Vea también esta respuesta , la solución actual es agregartheme(panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA))
Paul Rougieux
Considere marcar la segunda respuesta (por YRC) como aceptada debido a que las 'opciones' son obsoletas.
Davit Sargsyan

Respuestas:

70

Actualizado con la theme()función ggsave()y el código para el fondo de la leyenda:

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
  ) 

La forma más rápida es usar usando rect, ya que todos los elementos rectangulares heredan de rect:

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

La forma más controlada es usar opciones 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 guardar (este último paso es importante):

ggsave(p, filename = "tr_tst2.png",  bg = "transparent")
YCR
fuente
1
Si no configura el plot.backgroundcolor como la respuesta anterior, su trama tendrá un contorno tenue.
jsta
87

También hay una plot.backgroundopción además 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 alguna razón, la imagen cargada se muestra de manera diferente que en mi computadora, por lo que la he omitido. Pero para mí, obtengo una trama con un fondo completamente gris, excepto por la parte de la caja de la trama de la caja que todavía es blanca. Creo que eso también se puede cambiar usando la estética de relleno en el boxplot geom.

Editar

Desde entonces, ggplot2 ha sido actualizado y la opts()función ha quedado en desuso. Actualmente, usaría en theme()lugar de opts()y en element_rect()lugar de theme_rect(), etc.

joran
fuente
No esperaba que funcionara con una Mac cuando se prueba con el PowerPoint actual de esa plataforma, pero funciona como se anuncia. Y también funciona con archivos PDF si elimina las unidades y sustituye los tamaños en pulgadas Buen trabajo.
IRTFM
1
Esto funciona excelente con MS Powerpoint 2010. En realidad, lo necesitaba para este propósito.
Yuriy Petrovskiy
13
Si está utilizando ggsave, no olvide agregar bg = "transparent"para pasar al dispositivo de gráficos png.
Tom
12
Si está utilizando el knitrpaquete (o slidifyetc.), debe pasarlo dev.args = list(bg = 'transparent')como una opción fragmentaria. Más detalles aquí stackoverflow.com/a/13826154/561698
Andrew
3

Solo para mejorar la respuesta de YCR:

1) Agregué líneas negras en los ejes x e y. De lo contrario, también se hacen transparentes.

2) Agregué un tema transparente a la clave de la leyenda. De lo contrario, obtendrá un relleno allí, que no será muy estético.

Finalmente, tenga en cuenta que todos esos funcionan solo con formatos pdf y png. JPEG no produce 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
)
Rist
fuente