2013-05-03 10 views
17

Próbuję rozmieścić wiele działek przy użyciu grid.arrange. Czyni pracę przez książki, a kiedy dzwoni:Zachowaj proporcje wykresów za pomocą siatki.arrange

p1 <- ggplot(subset(mtcars, cyl = 4), aes(wt, mpg, colour = cyl)) + geom_point() 
p2 <- ggplot(subset(mtcars, cyl = 8), aes(wt, mpg, colour = cyl)) + geom_point() 

grid.arrange(p1, p2, ncol = 2) 

mam dwa ładne działki, symetryczne w rozmiarze:

enter image description here

moich wykresach odnoszą się do różnych parametrów, ale oni mają tych kodowanie tego samego koloru dla grup. Chciałbym usunąć legendę ze wszystkich oprócz jednego i znaleźć dla niej miłe miejsce.

Jednak gdy próbuję:

p3 <- ggplot(subset(mtcars, cyl = 8), aes(wt, mpg, colour = cyl)) + geom_point() + guides(colour=FALSE) 

grid.arrange(p3, p2, ncol = 2) 

Działka bez legendy dostaje (prawidłowo) większy:

enter image description here

Chciałbym utrzymać rozmiar (jako długość x oś), aby pozostać taka sama na wykresach.

Jestem świadomy, że przydałby szlifowaniem tutaj, ale również trzeba połączyć różne wykresy, że (chyba) będzie trudne do realizacji z wykorzystaniem aspektów ..

Czy można zrobić to z grid.arrange ? Jakieś inne rozwiązania, które mogłyby tutaj pomóc?

+0

Można to zrobić bez 'grid.arrange' przez szlifowania. Ale nie ma kolumny 'class' w' mtcars' dla mnie, aby to pokazać. – Arun

+0

@Arun SOrry - mój błąd. Przykład podłączenia do cylindrów. Jak już wspomniałem, zdaję sobie sprawę z magii faceting, jednak chciałbym uciec bez użycia go. – radek

Odpowiedz

11

Nie tak elegancko proste rozwiązanie @Josh „s, ale można to zrobić z grid.arrange który pozwala zachować lub określ współczynnik kształtu wykresów, ale musisz wprowadzić tableGrob dla swojej legendy. I odpowiedział na zblizonym pytanie here który gdzie mam kod przydatny do wytwarzania tableGrob z legendą ggplot2:

## Make a tableGrob of your legend 
tmp <- ggplot_gtable(ggplot_build(p2)) 
leg <- which(sapply(tmp$grobs, function(x) x$name) == "guide-box") 
legend <- tmp$grobs[[leg]] 

# Plot objects using widths and height and respect to fix aspect ratios 
# We make a grid layout with 3 columns, one each for the plots and one for the legend 
grid.newpage() 
pushViewport(viewport(layout = grid.layout(1 , 3 , widths = unit(c(0.4 , 0.4 , 0.2) , "npc") ,heights = unit(c(0.45 , 0.45 , 0.45) , "npc") , respect = matrix(rep(1,3),1)))) 
print(p1 + theme(legend.position="none") , vp = viewport(layout.pos.row = 1 , layout.pos.col = 1)) 
print(p2 + theme(legend.position="none") , vp = viewport(layout.pos.row = 1, layout.pos.col = 2)) 
upViewport(0) 
vp3 <- viewport(width = unit(0.2,"npc") , x = 0.9 , y = 0.5) 
pushViewport(vp3) 
grid.draw(legend) 
popViewport() 

enter image description here

+0

Wielkie dzięki. Chociaż dłuższe rozwiązanie spełnia swoją rolę. Dwa (nowicjusz) pytania: 1) Czy jednostki o szerokości mają sumę 1? Co to jest określenie "szacunku"? – radek

+2

Uważam, że argument respsect jest nieco mylący, ale zasadniczo uważam go za matrycę współczynnika proporcji dla każdego widoku, więc mamy '1,1,1', ponieważ mamy 1 wiersz i 3 kolumny i chcemy 1: 1 współczynnik proporcji w każdym. To może nie być * całkiem * jak to działa, ale pomaga mi! Jednostki o szerokości nie * mają * do sumy do 1. Możesz wycisnąć je w mniej niż szerokość obszaru kreślenia. "NPC" wynosi od 0 do 1, z 0 lewą krawędzią lub dolną częścią obszaru wykresu i 1 prawą krawędzią lub górą i 0,5 środkiem. Skaluj odpowiednio.] –

+0

Super. Teraz wszystko jasne. Dziękuję Ci. – radek

23

Spróbuj tego, który wykorzystuje cbind.gtable:

grid.draw(cbind(ggplotGrob(p3), ggplotGrob(p2), size="last")) 

enter image description here

+2

+1 Mam około 20 linii kodu właśnie miałem wkleić, aby osiągnąć to samo z odrobiną ręcznego manipulowania. Chciałbym * wcześniej wiedzieć o 'cbind.gtable'. Dzięki. –

+0

@Josh Dziękuję. Świetne rozwiązanie. Ale (tak samo jak Simon, muszę zapytać o współczynnik proporcji - czy można go zachować? – radek

+1

@ SimonO101 - Dobre pytanie, nie wygląda tak, jak to przewiduje. Jeśli któryś z was chce to osiągnąć, mogę zasugerować patrząc na 'getAnywhere (" cbind_gtable ")', w którym wydaje się, że jednostki się zestawiają, i gdzie możesz chcieć zmodyfikować kod –

Powiązane problemy