Сохранить пропорцию графиков с помощью grid.arrange

Я пытаюсь организовать несколько участков, используя grid.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)

Я получаю два симпатичных участка, симметричных по размеру:

Мои графики относятся к разным параметрам, но они имеют одинаковую цветовую кодировку для групп. Поэтому я хотел бы удалить легенду из всех, кроме одного, и найти для нее подходящее место.

Однако, когда я пытаюсь:

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

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

Сюжет без легенды становится (правильно) больше:

Я хотел бы сохранить размер (как длина оси X), чтобы остаться неизменным на графиках.

Я знаю, что я мог бы использовать здесь фасетирование, но мне также нужно будет комбинировать различные графики, которые (я думаю) будет сложно реализовать с использованием фасетов.

Можно ли сделать это с grid.arrange? Любые другие решения, которые могут помочь здесь?

2 ответа

Решение

Не так просто, как решение @Josh, но вы можете сделать это с помощью grid.arrange, который позволяет сохранить или указать соотношение сторон графиков, но вам нужно сделать tableGrob для вашей легенды. Здесь я ответил на аналогичный вопрос, где я получил удобный код для создания tableGrob из легенды 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()

Попробуйте это, который использует cbind.gtable:

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

Я думал, что обновлю эту тему, потому что grid.arrange теперь имеет такую ​​функциональность:

grid.arrange(p3, p2, ncol = 2, widths = c(1,1.2))

панели одинакового размера

Другие вопросы по тегам