Comment créer des graphiques avec un arrière-plan transparent dans R en utilisant ggplot2?

123

J'ai besoin de produire des graphiques ggplot2 à partir de fichiers R vers PNG avec un fond transparent. Tout va bien avec les graphiques R de base, mais pas de transparence avec 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-t-il un moyen d'obtenir un fond transparent avec ggplot2?

Yuriy Petrovskiy
la source
3
Voir aussi cette réponse , la solution actuelle est d'ajoutertheme(panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA))
Paul Rougieux
Veuillez envisager de marquer la deuxième réponse (par YRC) comme étant acceptée car les «opts» sont obsolètes.
Davit Sargsyan

Réponses:

70

Mis à jour avec la theme()fonction ggsave()et le code de l'arrière-plan de la légende:

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
  ) 

Le moyen le plus rapide est d'utiliser rect, car tous les éléments du rectangle héritent de rect:

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

Une manière plus contrôlée consiste à utiliser les options 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

Pour sauvegarder (cette dernière étape est importante):

ggsave(p, filename = "tr_tst2.png",  bg = "transparent")
YCR
la source
1
Si vous ne définissez pas la plot.backgroundcouleur comme la réponse ci-dessus, votre tracé aura un contour pâle.
jsta
87

Il existe également une plot.backgroundoption en plus 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()

Pour une raison quelconque, l'image téléchargée s'affiche différemment que sur mon ordinateur, je l'ai donc omise. Mais pour moi, j'obtiens un tracé avec un fond entièrement gris à l'exception de la partie boîte de la boîte à moustaches qui est toujours blanche. Cela peut également être changé en utilisant l'esthétique de remplissage dans le boxplot geom, je crois.

Éditer

ggplot2 a depuis été mis à jour et la opts()fonction est obsolète. Actuellement, vous utiliseriez theme()au lieu opts()et element_rect()au lieu de theme_rect(), etc.

joran
la source
Je ne m'attendais pas à ce qu'il fonctionne avec un Mac lorsqu'il est testé avec PowerPoint actuel de cette plate-forme, mais il fonctionne comme annoncé. Et cela fonctionne aussi avec les pdf si vous supprimez les unités et remplacez les tailles en pouces Bon travail.
IRTFM du
1
Cela fonctionne très bien avec MS Powerpoint 2010. En fait, j'en avais besoin pour cela.
Yuriy Petrovskiy
13
Si vous utilisez ggsave, n'oubliez pas d'ajouter bg = "transparent"pour passer au périphérique graphique png.
Tom
12
si vous utilisez le knitrpackage (ou slidifyetc), vous devez passer dev.args = list(bg = 'transparent')comme une option de bloc. Plus de détails ici stackoverflow.com/a/13826154/561698
Andrew
3

Juste pour améliorer la réponse de YCR:

1) J'ai ajouté des lignes noires sur les axes x et y. Sinon, ils sont également rendus transparents.

2) J'ai ajouté un thème transparent à la clé de légende. Sinon, vous y obtiendrez un remplissage, ce qui ne sera pas très esthétique.

Enfin, notez que tout cela fonctionne uniquement avec les formats pdf et png. jpeg ne parvient pas à produire des graphiques transparents.

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
la source