Выровнять по левому краю два графа графа (ggplot)
Я использую ggplot и имею два графика, которые я хочу отображать друг на друга. Я использовал grid.arrange
из gridExtra для их укладки. Проблема в том, что я хочу, чтобы левые края графов выравнивались так же, как и правые края, независимо от меток осей. (проблема возникает из-за того, что метки одного графика коротки, а другая длинна).
Вопрос:
Как я могу это сделать? Я не женат на grid.arrange, но ggplot2 является обязательным.
Что я пробовал:
Я пробовал играть с шириной и высотой, а также ncol и nrow, чтобы сделать сетку 2 x 2 и поместить визуальные изображения в противоположные углы, а затем играть с шириной, но я не мог получить визуальные эффекты в противоположных углах.
require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip()
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip()
grid.arrange(A, B, ncol=1)
![enter image description here]()
Ответы
Ответ 1
Попробуйте это,
gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5])
gA$widths[2:5] <- as.list(maxWidth)
gB$widths[2:5] <- as.list(maxWidth)
grid.arrange(gA, gB, ncol=1)
Изменить
Здесь более общее решение (работает с любым числом графиков) с использованием модифицированной версии rbind.gtable
, включенной в gridExtra
gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))
Ответ 2
Я хотел обобщить это для любого количества сюжетов. Вот пошаговое решение, использующее подход Baptiste:
plots <- list(A, B, C, D)
grobs <- list()
widths <- list()
собирать ширину для каждого графа каждого графика
for (i in 1:length(plots)){
grobs[[i]] <- ggplotGrob(plots[[i]])
widths[[i]] <- grobs[[i]]$widths[2:5]
}
используйте do.call, чтобы получить максимальную ширину
maxwidth <- do.call(grid::unit.pmax, widths)
присвоить максимальную ширину каждому гробу
for (i in 1:length(grobs)){
grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}
участок
do.call("grid.arrange", c(grobs, ncol = 1))
Ответ 3
Использование cowplot package:
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip()
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip()
library(cowplot)
plot_grid(A, B, ncol=1, align="v")
![введите описание изображения здесь]()
Ответ 4
В http://rpubs.com/MarkusLoew/13295 доступно очень простое решение (последний элемент)
Применительно к этой проблеме:
require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip()
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip()
grid.draw(rbind(ggplotGrob(A), ggplotGrob(B), size="first"))
вы также можете использовать это для ширины и высоты:
require(ggplot2);require(gridExtra)
A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip()
B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip()
C <- ggplot(CO2, aes(x=conc)) + geom_bar() +coord_flip()
D <- ggplot(CO2, aes(x=uptake)) + geom_bar() +coord_flip()
grid.draw(cbind(
rbind(ggplotGrob(A), ggplotGrob(B), size="first"),
rbind(ggplotGrob(C), ggplotGrob(D), size="first"),
size='first'))
Ответ 5
Вот еще одно возможное решение, использующее melt
из пакета reshape2 и facet_wrap
:
library(ggplot2)
library(reshape2)
dat = CO2[, c(1, 2)]
dat$id = seq(nrow(dat))
mdat = melt(dat, id.vars="id")
head(mdat)
# id variable value
# 1 1 Plant Qn1
# 2 2 Plant Qn1
# 3 3 Plant Qn1
# 4 4 Plant Qn1
# 5 5 Plant Qn1
# 6 6 Plant Qn1
plot_1 = ggplot(mdat, aes(x=value)) +
geom_bar() +
coord_flip() +
facet_wrap(~ variable, nrow=2, scales="free", drop=TRUE)
ggsave(plot=plot_1, filename="plot_1.png", height=4, width=6)
![enter image description here]()
Ответ 6
Пакет egg
обертывает объекты ggplot стандартизованным 3x3
gtable, позволяя выравнивать панели сюжетов между произвольными ggplots, включая фасетные.
library(egg) # devtools::install_github('baptiste/egg')
library(ggplot2)
p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
geom_point()
p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) +
geom_point() + facet_wrap( ~ cyl, ncol=2, scales = "free") +
guides(colour="none") +
theme()
ggarrange(p1, p2)
![введите описание изображения здесь]()
Ответ 7
В лучшем случае это взломать:
library(wq)
layOut(list(A, 1, 2:16), list(B, 2:3, 1:16))
Он чувствует себя действительно неправильно, хотя.