使用 gtable 排列 ggplot 图(具有相同宽度的 grobs)以创建 2x2 布局
Arrange ggplot plots (grobs with same widths) using gtable to create 2x2 layout
我正在尝试使用 grobs 和 gtable 将 4 (ggplot2) 个绘图排列成 2x2 网格。我不知道如何设置宽度,以及非 1xn 或 nx1 排列。
使用此代码:
data(iris)
a <- ggplot(iris, aes(x=Species, y=Petal.Width)) + geom_boxplot(color="black") + ylab(expression(Foo~Bar~(g~cm^{-3})))
b <- ggplot(iris, aes(x=Species, y=Petal.Length*100)) + geom_boxplot(color="black") + ylab("foobar (mm)")
c <- ggplot(iris, aes(x=Species, y=Sepal.Width)) + geom_boxplot(color="black") + ylab("foobar (%)")
d <- ggplot(iris, aes(x=Species, y=log10(Sepal.Length))) + geom_boxplot(color="black") + ylab("foobar (cm)")
plots <- list(a,b,c,d)
grobs = lapply(plots, ggplotGrob)
g = do.call(rbind, c(grobs, size="first"))
g$widths = do.call(unit.pmax, lapply(grobs, "[[", "widths"))
grid.newpage()
grid.draw(g)
我可以创建以下 1x4 排列。
如果我对两列使用 grid.arrange,在 4 个图上,图的宽度不同。
如何将绘图绑定到 gtable 以进行 4 x 4 排列?
# I thought maybe I could cbind, then rbind, but this does not work
plots1 <- list(a,b)
plots2 <- list(c,d)
grobs1 = lapply(plots1, ggplotGrob)
grobs2 = lapply(plots2, ggplotGrob)
g1 = do.call(cbind, c(grobs1, size="first"))
g2 = do.call(cbind, c(grobs2, size="first"))
# g3 = do.call(rbind, c(g1,g2, size="first")) #this does not work
我想你已经有了答案。
你的最后一行 returns 是一个错误,但是一个小的编辑会产生一个组合图,其中列内的宽度是相同的:
g3 = do.call(rbind, c(list(g1,g2), size="first")) #combine g1 and g2 into a list
aesthetics/reference 的旁注:
如果你的x轴相同,你可以把它从上面的两个图中去掉。
library(ggplot2); library(gridExtra); library(grid)
# Tweak the margins to use up empty space. Margins: Top, Right, Bottom, Left
# For reference: a1= top left, b1= top right
# c1= bottom left, d1= bottom right
a1 <- a + theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x= element_blank(),
plot.margin= unit(c(1, 1, -0.5, 0.5), "lines") )
b1 <- b + theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x= element_blank(),
plot.margin= unit(c(1, 1, -0.5, 0.5), "lines") )
c1 <- c + theme(plot.margin= unit(c(0, 1, 0.5, 0.5), "lines") )
d1 <- d + theme(plot.margin= unit(c(0, 1, 0.5, 0.5), "lines") )
grobz <- lapply(list(a1, b1, c1, d1), ggplotGrob)
grobz.plot <- arrangeGrob( grobs = list(rbind(grobz[[1]], grobz[[3]], size = "last"),
rbind(grobz[[2]], grobz[[4]], size = "last")),
ncol = 2)
grid.draw(grobz.plot)
这些 Whosebug 问题有助于对齐图:
- 在 gtable 中使用
rbind
设置绘图宽度 (Baptiste) [link]
- gtable (Baptiste) 中的相对面板高度 [link]
- 绘图宽度和图例 [link]
这对你有用吗
library(cowplot)
library(ggplot2)
data(iris)
a <- ggplot(iris, aes(x=Species, y=Petal.Width)) + geom_boxplot(color="black") + ylab(expression(Foo~Bar~(g~cm^{-3}))) + theme_grey()
b <- ggplot(iris, aes(x=Species, y=Petal.Length*100)) + geom_boxplot(color="black") + ylab("foobar (mm)") + theme_grey()
c <- ggplot(iris, aes(x=Species, y=Sepal.Width)) + geom_boxplot(color="black") + ylab("foobar (%)") + theme_grey()
d <- ggplot(iris, aes(x=Species, y=log10(Sepal.Length))) + geom_boxplot(color="black") + ylab("foobar (cm)") + theme_grey()
plot_grid(a,b, c, d, ncol=2,align="v")
与上面的非常相似,但是使用了 gtable 函数*
library(ggplot2)
pl <- list(ggplot() + xlab("x"),
ggplot() + ylab("y"),
ggplot() + ylab("y"),
ggplot() + ggtitle("title") + xlab("x"))
library(grid)
library(gridExtra)
gl <- lapply(pl, ggplotGrob)
# gt <- cbind(rbind(gl[[1]], gl[[3]]),
# rbind(gl[[2]], gl[[4]]))
# alternative to remove x-axes of top row of plots
gt <- cbind(rbind(gl[[1]][1:3,], gl[[3]]),
rbind(gl[[2]][1:3,], gl[[4]]))
grid.newpage()
grid.draw(gt)
*:实际上,因为 gtable doesn't allow the use of pmax when comparing units, this is using a drop-in replacement from the dev version of gridExtra.
我正在尝试使用 grobs 和 gtable 将 4 (ggplot2) 个绘图排列成 2x2 网格。我不知道如何设置宽度,以及非 1xn 或 nx1 排列。
使用此代码:
data(iris)
a <- ggplot(iris, aes(x=Species, y=Petal.Width)) + geom_boxplot(color="black") + ylab(expression(Foo~Bar~(g~cm^{-3})))
b <- ggplot(iris, aes(x=Species, y=Petal.Length*100)) + geom_boxplot(color="black") + ylab("foobar (mm)")
c <- ggplot(iris, aes(x=Species, y=Sepal.Width)) + geom_boxplot(color="black") + ylab("foobar (%)")
d <- ggplot(iris, aes(x=Species, y=log10(Sepal.Length))) + geom_boxplot(color="black") + ylab("foobar (cm)")
plots <- list(a,b,c,d)
grobs = lapply(plots, ggplotGrob)
g = do.call(rbind, c(grobs, size="first"))
g$widths = do.call(unit.pmax, lapply(grobs, "[[", "widths"))
grid.newpage()
grid.draw(g)
我可以创建以下 1x4 排列。
如果我对两列使用 grid.arrange,在 4 个图上,图的宽度不同。
如何将绘图绑定到 gtable 以进行 4 x 4 排列?
# I thought maybe I could cbind, then rbind, but this does not work
plots1 <- list(a,b)
plots2 <- list(c,d)
grobs1 = lapply(plots1, ggplotGrob)
grobs2 = lapply(plots2, ggplotGrob)
g1 = do.call(cbind, c(grobs1, size="first"))
g2 = do.call(cbind, c(grobs2, size="first"))
# g3 = do.call(rbind, c(g1,g2, size="first")) #this does not work
我想你已经有了答案。
你的最后一行 returns 是一个错误,但是一个小的编辑会产生一个组合图,其中列内的宽度是相同的:
g3 = do.call(rbind, c(list(g1,g2), size="first")) #combine g1 and g2 into a list
aesthetics/reference 的旁注:
如果你的x轴相同,你可以把它从上面的两个图中去掉。
library(ggplot2); library(gridExtra); library(grid)
# Tweak the margins to use up empty space. Margins: Top, Right, Bottom, Left
# For reference: a1= top left, b1= top right
# c1= bottom left, d1= bottom right
a1 <- a + theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x= element_blank(),
plot.margin= unit(c(1, 1, -0.5, 0.5), "lines") )
b1 <- b + theme(axis.title.x = element_blank(),
axis.text.x = element_blank(),
axis.ticks.x= element_blank(),
plot.margin= unit(c(1, 1, -0.5, 0.5), "lines") )
c1 <- c + theme(plot.margin= unit(c(0, 1, 0.5, 0.5), "lines") )
d1 <- d + theme(plot.margin= unit(c(0, 1, 0.5, 0.5), "lines") )
grobz <- lapply(list(a1, b1, c1, d1), ggplotGrob)
grobz.plot <- arrangeGrob( grobs = list(rbind(grobz[[1]], grobz[[3]], size = "last"),
rbind(grobz[[2]], grobz[[4]], size = "last")),
ncol = 2)
grid.draw(grobz.plot)
这些 Whosebug 问题有助于对齐图:
- 在 gtable 中使用
rbind
设置绘图宽度 (Baptiste) [link] - gtable (Baptiste) 中的相对面板高度 [link]
- 绘图宽度和图例 [link]
这对你有用吗
library(cowplot)
library(ggplot2)
data(iris)
a <- ggplot(iris, aes(x=Species, y=Petal.Width)) + geom_boxplot(color="black") + ylab(expression(Foo~Bar~(g~cm^{-3}))) + theme_grey()
b <- ggplot(iris, aes(x=Species, y=Petal.Length*100)) + geom_boxplot(color="black") + ylab("foobar (mm)") + theme_grey()
c <- ggplot(iris, aes(x=Species, y=Sepal.Width)) + geom_boxplot(color="black") + ylab("foobar (%)") + theme_grey()
d <- ggplot(iris, aes(x=Species, y=log10(Sepal.Length))) + geom_boxplot(color="black") + ylab("foobar (cm)") + theme_grey()
plot_grid(a,b, c, d, ncol=2,align="v")
与上面的非常相似,但是使用了 gtable 函数*
library(ggplot2)
pl <- list(ggplot() + xlab("x"),
ggplot() + ylab("y"),
ggplot() + ylab("y"),
ggplot() + ggtitle("title") + xlab("x"))
library(grid)
library(gridExtra)
gl <- lapply(pl, ggplotGrob)
# gt <- cbind(rbind(gl[[1]], gl[[3]]),
# rbind(gl[[2]], gl[[4]]))
# alternative to remove x-axes of top row of plots
gt <- cbind(rbind(gl[[1]][1:3,], gl[[3]]),
rbind(gl[[2]][1:3,], gl[[4]]))
grid.newpage()
grid.draw(gt)
*:实际上,因为 gtable doesn't allow the use of pmax when comparing units, this is using a drop-in replacement from the dev version of gridExtra.