如何使用 ggplot2、gridExtra 对齐和缩放不同维度的图?
How to align and scale plots of different dimensions with ggplot2, gridExtra?
我正在尝试使用 ggplot2 和 gridExtra 生成并排的平铺图。
但是,生成的图不是scaled/aligned,见下图和代码。
如何生成此图,使单元格对齐且尺寸相同?
代码
library(ggplot2)
library(gridExtra)
## make date frames
one <- floor(runif(56, min=0, max=5))
data.one<- cbind(one,expand.grid(h = seq(1,8,1), w = seq(1,7,1)))
two <- floor(runif(35, min=0, max=5))
data.two <- cbind(two,expand.grid(h = seq(1,7,1), w = seq(1,5,1)))
## gridExtra layout
lay <- rbind(c(1,1,1,1,1,1,1,NA,NA,NA,NA,NA),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2))
##plots
plot.one<-ggplot(data=data.one)+
geom_tile(aes(x=w,y=h,fill=one),colour = "grey50")+
scale_fill_gradient(low = "white", high = "blue")+
theme(legend.position= "none")
plot.two<-ggplot(data=data.two)+
geom_tile(aes(y=h,x=w,fill=two),colour = "grey50")+
scale_fill_gradient(low = "white", high = "red")+
theme(legend.position= "none")
grid.arrange(plot.one,plot.two, layout_matrix = lay)
ggplot2 不会为绘图面板分配固定大小,因此您需要进入相当低的级别,找出每个绘图中的 bin 数量,并使用它来设置适当的面板大小gtable 对象。另一个复杂的问题是 "null" 单位在网格中有点特殊,所以要有一些与它们一起缩放的东西,它本身需要是一个空单位,就像这个虚拟 rectGrob 从顶部挤压第二个绘图面板一样,
b1 <- ggplot_build(p1)
b2 <- ggplot_build(p2)
n <- function(b) length(unique(b[["data"]][[1]][["y"]]))
library(egg)
library(grid)
gf1 <- gtable_frame(ggplot_gtable(b1))
gf2 <- gtable_frame(ggplot_gtable(b2))
gf2$grobs[[5]][["grobs"]][[1]] <- arrangeGrob(
rectGrob(gp=gpar(fill="grey95", col=NA)), gf2$grobs[[5]][["grobs"]][[1]],
heights = unit.c(unit(1 - n(b2) / n(b1), "null"), unit(n(b2) / n(b1),"null")))
grid.arrange(gf1, gf2, ncol=2)
我正在尝试使用 ggplot2 和 gridExtra 生成并排的平铺图。 但是,生成的图不是scaled/aligned,见下图和代码。
如何生成此图,使单元格对齐且尺寸相同?
library(ggplot2)
library(gridExtra)
## make date frames
one <- floor(runif(56, min=0, max=5))
data.one<- cbind(one,expand.grid(h = seq(1,8,1), w = seq(1,7,1)))
two <- floor(runif(35, min=0, max=5))
data.two <- cbind(two,expand.grid(h = seq(1,7,1), w = seq(1,5,1)))
## gridExtra layout
lay <- rbind(c(1,1,1,1,1,1,1,NA,NA,NA,NA,NA),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2),
c(1,1,1,1,1,1,1,2,2,2,2,2))
##plots
plot.one<-ggplot(data=data.one)+
geom_tile(aes(x=w,y=h,fill=one),colour = "grey50")+
scale_fill_gradient(low = "white", high = "blue")+
theme(legend.position= "none")
plot.two<-ggplot(data=data.two)+
geom_tile(aes(y=h,x=w,fill=two),colour = "grey50")+
scale_fill_gradient(low = "white", high = "red")+
theme(legend.position= "none")
grid.arrange(plot.one,plot.two, layout_matrix = lay)
ggplot2 不会为绘图面板分配固定大小,因此您需要进入相当低的级别,找出每个绘图中的 bin 数量,并使用它来设置适当的面板大小gtable 对象。另一个复杂的问题是 "null" 单位在网格中有点特殊,所以要有一些与它们一起缩放的东西,它本身需要是一个空单位,就像这个虚拟 rectGrob 从顶部挤压第二个绘图面板一样,
b1 <- ggplot_build(p1)
b2 <- ggplot_build(p2)
n <- function(b) length(unique(b[["data"]][[1]][["y"]]))
library(egg)
library(grid)
gf1 <- gtable_frame(ggplot_gtable(b1))
gf2 <- gtable_frame(ggplot_gtable(b2))
gf2$grobs[[5]][["grobs"]][[1]] <- arrangeGrob(
rectGrob(gp=gpar(fill="grey95", col=NA)), gf2$grobs[[5]][["grobs"]][[1]],
heights = unit.c(unit(1 - n(b2) / n(b1), "null"), unit(n(b2) / n(b1),"null")))
grid.arrange(gf1, gf2, ncol=2)