我正在尝试使用共享轴和边缘直方图创建三个散点图的排列。这似乎应该很简单,但它给了我适合。我已经尝试过使用gridExtra和gtable的方法,这两种方法都得到了我想要的一般排列,但是对齐和绘图大小已经关闭。
还有很多与这个问题相关的帖子,我已经尝试了很多答案,特别是@baptiste here和here的答案。后者控制宽度的方法可能是对齐的关键,但我还没有完全理解它以适应我的问题。
接下来是一个最小的工作示例,前面是其结果。结果有很多问题:
即使轴标签的宽度在不同图形之间变化,也能正确对齐图形轴的答案的加分点,因此可以更好地适应未来的问题。
library(ggplot2)
library(grid)
library(gtable)
data <- data.frame(a = rnorm(100, 30, 3), b = rnorm(100, 40, 5), c=rnorm(100, 50, 3))
b_a.scatter <- ggplot(data, aes(x=a, y=b)) + geom_point() + coord_equal(ratio=1, xlim=c(0,100), ylim=c(0,100)) +
theme(
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.ticks.x = element_blank(),
plot.margin = unit(c(1,0,-0.5,1), "cm")
)
c_a.scatter <- ggplot(data, aes(x=a, y=c)) + geom_point() + coord_equal(ratio=1, xlim=c(0,100), ylim=c(0,100)) +
theme(plot.margin = unit(c(-0.5,0,0.5,1), "cm"))
c_b.scatter <- ggplot(data, aes(x=b, y=c)) + geom_point() + coord_equal(ratio=1, xlim=c(0,100), ylim=c(0,100)) +
theme(
axis.text.y = element_blank(),
axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
plot.margin = unit(c(-0.5,0,0.5,0), "cm")
)
a.hist <- ggplot(data, aes(x=a)) + geom_histogram() + coord_equal(xlim=c(0,100), ratio=1/4) +
theme(
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.y = element_blank(),
axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
plot.margin = unit(c(0,0,1,1), "cm")
)
b.hist <- ggplot(data, aes(x=b)) + geom_histogram() + coord_equal(xlim=c(0,100), ratio=1/4) +
theme(
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.ticks.x = element_blank(),
axis.text.y = element_blank(),
axis.title.y = element_blank(),
axis.ticks.y = element_blank(),
plot.margin = unit(c(0,0,1,0), "cm")
)
c.hist <- ggplot(data, aes(x=c)) + geom_histogram() + coord_flip(xlim=c(0,100)) +
theme(
axis.text.x = element_blank(),
axis.title.x = element_blank(),
axis.ticks.x = element_blank(),
plot.margin = unit(c(0,1,0,0), "cm")
)
blankPanel <- grid.rect(gp=gpar(col="white"))
gt <- gtable(widths = unit(rep(1,9), "null"),
heights = unit(rep(1,9), "null"),
respect=T)
gl <- list(ggplotGrob(b_a.scatter),
ggplotGrob(c_a.scatter), ggplotGrob(c_b.scatter), ggplotGrob(c.hist),
ggplotGrob(a.hist), ggplotGrob(b.hist))
gt <- gtable_add_grob(gt, gl,
l=c(1,1,5,9,1,5),
r=c(4,4,8,9,4,8),
t=c(1,5,5,5,9,9),
b=c(4,8,8,8,9,9))
grid.newpage()
png('multiplot.png')
grid.draw(gt)
dev.off()
答案 0 :(得分:2)
这是一种方法:使用rbind逐列组合图形,然后cbind三列。为空单元格提供了虚拟gtables,它们只包含布局信息。
library(ggplot2)
library(gtable)
d <- data.frame(a = rnorm(100, 30, 3),
b = rnorm(100, 40, 5),
c=rnorm(100, 50, 3))
theme_set(theme_bw() +
theme(plot.background=element_rect(colour="red",size = 2)))
## define simpler plots
a <- ggplot(d, aes(x=a, y=b)) + geom_point() + xlim(0,100)+ ylim(0,90)
b <- ggplot(d, aes(x=a, y=c)) + geom_point() + xlim(0,100) + ylim(0,90)
c <- ggplot(d, aes(x=b, y=c)) + geom_point() + xlim(0,100) + ylim(0,90)
ah <- ggplot(d, aes(x=a)) + geom_histogram() +
xlim(0,100)+ ylim(0,2000000)
bh <- ggplot(d, aes(x=b)) + geom_histogram() +
xlim(0,100) + ylim(0,2000000)
ch <- ggplot(d, aes(x=c)) + geom_histogram() +
coord_flip(xlim=c(0,200000))
pl <- lapply(list(a,b,c,ah,bh,ch), ggplotGrob)
## function to create a dummy table (no grobs, zero size) of the right dim for (r/c)bind
dummy_gtable <- function(g){
gtable(widths=unit(rep(0,ncol(g)), 'null'), heights=unit(rep(0, nrow(g)), 'null'))
}
left <- rbind(pl[[1]],pl[[2]],pl[[4]])
middle <- rbind(dummy_gtable(pl[[1]]),pl[[3]],pl[[5]])
right <- rbind(dummy_gtable(pl[[1]]),pl[[6]], dummy_gtable(pl[[5]]))
grid.newpage()
grid.draw(cbind(left, middle, right))
请注意,我使用my experimental fork of gtable中的cbind
和rbind
,因为发布的版本不使用unit.pmax
作为宽度和高度的单位比较。可以从another question借用自定义函数以继续使用稳定的gtable版本。