Jak zrobić grafikę z przezroczystym tłem w R używając ggplot2?

123

Muszę wypisać grafikę ggplot2 z plików R do PNG z przezroczystym tłem. Wszystko jest w porządku z podstawową grafiką R, ale brak przejrzystości w 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()

Czy jest sposób na uzyskanie przezroczystego tła za pomocą ggplot2?

Yuriy Petrovskiy
źródło
3
Zobacz także tę odpowiedź , obecnym rozwiązaniem jest dodanietheme(panel.background = element_rect(fill = "transparent", colour = NA), plot.background = element_rect(fill = "transparent", colour = NA))
Paul Rougieux
Proszę rozważyć oznaczenie drugiej odpowiedzi (przez YRC) jako zaakceptowanej, ponieważ „opcje” są nieaktualne.
Davit Sargsyan

Odpowiedzi:

70

Zaktualizowano o theme()funkcję ggsave()i kod tła legendy:

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
  ) 

Najszybszym sposobem jest użycie rect, ponieważ wszystkie elementy prostokąta dziedziczą po rect:

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

Bardziej kontrolowanym sposobem jest użycie opcji 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

Aby zapisać (ten ostatni krok jest ważny):

ggsave(p, filename = "tr_tst2.png",  bg = "transparent")
YCR
źródło
1
Jeśli nie ustawisz plot.backgroundkoloru, takiego jak odpowiedź powyżej, wykres będzie miał słaby zarys.
jsta
87

Istnieje również plot.backgroundopcja oprócz 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()

Z jakiegoś powodu przesłany obraz wyświetla się inaczej niż na moim komputerze, więc pominąłem go. Ale dla mnie otrzymuję wykres z całkowicie szarym tłem, z wyjątkiem części pudełkowej wykresu pudełkowego, która jest nadal biała. Wydaje mi się, że można to zmienić za pomocą estetyki wypełnienia w wykresie pudełkowym.

Edytować

ggplot2 został od tego czasu zaktualizowany, a opts()funkcja jest przestarzała. Obecnie używałbyś theme()zamiast opts()i element_rect()zamiast theme_rect()itp.

joran
źródło
Nie spodziewałem się, że będzie działać z komputerem Mac podczas testowania z obecnym programem PowerPoint tej platformy, ale działa zgodnie z reklamą. Działa również z plikami PDF, jeśli usuniesz jednostki i zastąpisz rozmiary w calach Dobra robota.
IRTFM
1
Działa to doskonale z MS Powerpoint 2010. Właściwie potrzebowałem go do tego celu.
Yuriy Petrovskiy
13
Jeśli używasz ggsave, nie zapomnij dodać, bg = "transparent"aby przejść do urządzenia graficznego png.
Tom
12
jeśli używasz knitrpakietu (lub slidifyitp.), musisz podać dev.args = list(bg = 'transparent')jako opcję porcji. Więcej szczegółów tutaj stackoverflow.com/a/13826154/561698
Andrew
3

Aby poprawić odpowiedź YCR:

1) Dodałem czarne linie na osi x i y. W przeciwnym razie są również przezroczyste.

2) Dodałem przezroczysty motyw do klucza legendy. W przeciwnym razie dostaniesz tam wypełnienie, które nie będzie zbyt estetyczne.

Na koniec zwróć uwagę, że wszystkie one działają tylko z formatami pdf i png. jpeg nie tworzy przezroczystych wykresów.

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
źródło