2013-02-12 9 views
16

mam tej ramki danych:Place legenda dla każdego siatki facet_wrap w ggplot2

 Date Server FileSystem PercentUsed 
1 12/1/2011  A  /  60 
2 1/2/2012  A  /var   50 
3 2/1/2012  A  tmp   90 
4 2/10/2012  A  /db   86 
5 2/13/2012  A  /app   90 
6 12/1/2011  B   C:   67 
7 1/2/2012  B   D:   67 
8 2/1/2012  B   F:   34 
9 2/10/2012  B /restore   89 
10 2/13/2012  B   G:   56 
11 12/1/2011  C  /  90 
12 1/2/2012  C  /tmp   78 
13 2/1/2012  C  /data   67 
14 2/10/2012  C /Storage   34 
15 2/13/2012  C /database   12 

dput(x) 
structure(list(Date = structure(c(2L, 1L, 3L, 4L, 5L, 2L, 1L, 
3L, 4L, 5L, 2L, 1L, 3L, 4L, 5L), .Label = c("1/2/2012", "12/1/2011", 
"2/1/2012", "2/10/2012", "2/13/2012"), class = "factor"), Server = structure(c(1L, 
1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L), .Label = c("A", 
"B", "C"), class = "factor"), FileSystem = structure(c(1L, 9L, 
14L, 5L, 2L, 10L, 11L, 12L, 6L, 13L, 1L, 8L, 3L, 7L, 4L), .Label = c("/", 
"/app", "/data", "/database", "/db", "/restore", "/Storage", 
"/tmp", "/var", "C:", "D:", "F:", "G:", "tmp"), class = "factor"), 
    PercentUsed = c(60L, 50L, 90L, 86L, 90L, 67L, 67L, 34L, 89L, 
    56L, 90L, 78L, 67L, 34L, 12L)), .Names = c("Date", "Server", 
"FileSystem", "PercentUsed"), class = "data.frame", row.names = c(NA, 
-15L)) 

chciałbym umieścić legendę obok każdego facet_wrap siatki, własny FileSystem:

Kiedy zrobić to umieszcza legendę po stronie działki dla wszystkich FileSystem. Czy można umieścić FileSystem przy każdym serwerze obok każdej siatki?

ggplot(x, aes(Date, PercentUsed, group=1, colour=FileSystem)) + 
    geom_jitter(size=0.5) + geom_smooth(method="loess", se=T) + 
    facet_wrap(~Server, ncol=1) 

Odpowiedz

19

Meh, @joran mnie uprzedził (mój gridExtra był nieaktualny ale wziął mi 10 minut, aby to sobie uświadomić). Oto podobne rozwiązanie, ale ten ogólnie maskuje kota według poziomów w Server.

library(gridExtra) 
out <- by(data = x, INDICES = x$Server, FUN = function(m) { 
     m <- droplevels(m) 
     m <- ggplot(m, aes(Date, PercentUsed, group=1, colour = FileSystem)) + 
     geom_jitter(size=2) + geom_smooth(method="loess", se=T) 
    }) 
do.call(grid.arrange, out) 

# If you want to supply the parameters to grid.arrange 
do.call(grid.arrange, c(out, ncol=3)) 

image

+0

Bardzo ładne. Nie zdawałem sobie sprawy, że 'droplevels()' ma metodę dla 'data.frame's. To jest przydatne! –

+0

Czy istnieje sposób na wymuszenie wyrównania, tzn. Czy szerokość obszaru wydruku jest taka sama? Przepisać szerokość legendy? – mlt

+0

@mlt rozważ przeniesienie legendy na początek pierwszej figury i usuń ją z pozostałych. –

19

Najlepszym sposobem na to jest z gridExtra opakowania:

library(gridExtra) 

xs <- split(x,f = x$Server) 
p1 <- ggplot(xs$A,aes(x = Date,y = PercentUsed,group = 1,colour = FileSystem)) + 
     geom_jitter(size=0.5) + 
     geom_smooth(method="loess", se=T) + 
     facet_wrap(~Server, ncol=1) 

p2 <- p1 %+% xs$B 
p3 <- p1 %+% xs$C 

grid.arrange(p1,p2,p3) 

enter image description here

+0

Należy zauważyć, że dokonane punkty bardzo małe w 'geom_jitter' i nie jestem pewien dlaczego, ale zostawiłem go tak jak jest. Punkty są tam, ale trudno je zobaczyć. – joran

+1

Jestem trochę zaintrygowany operatorem '% +%'. Czy możesz wyjaśnić, co robi? – Legend

+2

@Legend To sposób na uczynienie obiektu ggplot "modułem" w tym sensie, że można go użyć po prostu upuścić w nowej ramce danych, ale używać wszystkich tych samych specyfikacji geom z poprzedniej fabuły. Oczywiście zadziała to tylko wtedy, gdy wszystkie kolumny będą pasować do siebie i jeśli nie używałeś innych ramek danych na innych warstwach. – joran

2

Zamiast aspekty, możemy zrobić listę działek w grupie, a następnie użyć cowplot :: plot_grid do kreślenia. Każdy będzie miał swoją własną legendę:

# make list of plots 
ggList <- lapply(split(x, x$Server), function(i) { 
    ggplot(i, aes(Date, PercentUsed, group = 1, colour = FileSystem)) + 
    geom_jitter(size = 2) + 
    geom_smooth(method = "loess", se = TRUE)}) 

# plot as grid in 1 columns 
cowplot::plot_grid(plotlist = ggList, ncol = 1, 
        align = 'v', labels = levels(x$Server)) 

Jak sugeruje @Axeman, moglibyśmy dodać etykiety za pomocą facet_grid(~Server) zamiast labels = levels(x$Server).

enter image description here

+1

Świetnie. Jeśli chcesz, aby szare paski aspektu były wyświetlane, nadal możesz dodać '+ facet_grid (~ Server)'. Użycie 'align = 'v'' w' plot_grid' da lepszy wynik. – Axeman

+1

@Amanem dobry punkt o "v", dziękuję, zaktualizowany.Chciałem uniknąć używania aspektu, dlatego użyłem etykiety. – zx8754

Powiązane problemy