两个ggplot2图形的顶部对齐问题

4
我知道 ggExtra 包中的 align.plots 函数已被弃用并移除。然而,我正在使用自己的版本,因为它似乎提供了我需要的特定功能。我已经研究过分面图来解决我的问题,但我认为它不适用于我的特定问题。问题似乎在于当我在其中一个图上使用 coord_equal 时,从上到下的图像无法对齐。但这似乎不影响从左到右的图像。以下是我尝试实现的简化版本(或者至少是我能做到的最简化版本)。
创建一些虚拟数据框:
source('https://raw.github.com/jbryer/multilevelPSA/master/r/align.R')
require(psych)
df = data.frame(x=rnorm(100, mean=50, sd=10),
            y=rnorm(100, mean=48, sd=10),
            group=rep(letters[1:10], 10))
dfx = describe.by(df$x, df$group, mat=TRUE)[,c('group1', 'mean', 'n', 'min', 'max')]
names(dfx) = c('group', 'x', 'x.n', 'x.min', 'x.max')
dfy = describe.by(df$y, df$group, mat=TRUE)[,c('group1', 'mean', 'n', 'min', 'max')]
names(dfy) = c('group', 'y', 'y.n', 'y.min', 'y.max')
df2 = cbind(dfx, dfy[,2:ncol(dfy)])
range = c(0,100)

这将设置三个图表:
p1a = ggplot(df2, aes(x=x, y=y, colour=group)) + geom_point() + 
    opts(legend.position='none') +
    scale_x_continuous(limits=range) + scale_y_continuous(limits=range)
p1 = p1a + coord_equal(ratio=1)
p2 = ggplot(df, aes(x=x, y=group, colour=group)) + geom_point() +   
    scale_x_continuous(limits=range) + opts(legend.position='none')
p3 = ggplot(df, aes(x=group, y=y, colour=group)) + geom_point() + 
    scale_y_continuous(limits=range) + opts(legend.position='none')

使用coord_equal时,上下对齐无效。

grid_layout <- grid.layout(nrow=2, ncol=2, widths=c(1,2), heights=c(2,1))
grid.newpage()
pushViewport( viewport( layout=grid_layout, width=1, height=1 ) )
align.plots(grid_layout, list(p1, 1, 2), list(p3, 1, 1), list(p2, 2, 2))

损坏的图表 http://bryer.org/alignplots1.png

解决方法是在grid.layout语句中添加respect=TRUE:

grid_layout <- grid.layout(nrow=2, ncol=2, widths=c(1,2), heights=c(2,1), respect=TRUE)

但如果我不使用coord_equal,对齐就能正常工作:

grid_layout <- grid.layout(nrow=2, ncol=2, widths=c(1,2), heights=c(2,1))
grid.newpage()
pushViewport( viewport( layout=grid_layout, width=1, height=1 ) )
align.plots(grid_layout, list(p1a, 1, 2), list(p3, 1, 1), list(p2, 2, 2))

Working Plot http://bryer.org/alignplots2.png


@詹姆斯,看一下最右边两个图的x轴。它们在第二个版本中对齐了。 - Gregor Thomas
但是我对第二个版本有些困惑。如果不使用coord_equal可以使事情正常工作,那就不要使用它。 - Gregor Thomas
没错,shujaa。唯一的区别是在第一个图中我使用了coord_equal来设置右上角的坐标轴。对于我的目的,保持x和y轴相等非常重要。谢谢。 - jbryer
你尝试过在Github上使用Kohske的开发分支吗?他有一些类似于你的例子,使用了gtable。 - baptiste
@baptiste 感谢您的引荐。我会研究Kohske的工作。 - jbryer
显示剩余2条评论
3个回答

4

现在,ggplot2已经有了ggplotGrob()函数,这可能有所帮助。

首先,我们需要更新用于生成图表的代码:

p1a = ggplot(df2, aes(x=x, y=y, colour=group)) + geom_point()  +
  scale_x_continuous(limits=range) + scale_y_continuous(limits=range)
p1 = p1a + coord_equal(ratio=1) + theme_minimal() + theme(legend.position='none')
p2 = ggplot(df, aes(x=x, y=group, colour=group)) + geom_point() +   
  scale_x_continuous(limits=range) + theme_minimal() + theme(legend.position='none')
p3 = ggplot(df, aes(x=group, y=y, colour=group)) + geom_point() + 
  scale_y_continuous(limits=range) + theme_minimal() + theme(legend.position='none') 
p4 <- ggplot(df, aes(x = group, y = y)) + 
  geom_blank() +
  theme(line = element_blank(),
        rect = element_blank(),
        text = element_blank(),
        title = element_blank())

p4将会是空白的;我们只需要绘制grob。

然后我们加载grid包并使用cbind()rbind()按行列排列的列表来绘制grob。

library(grid)
grid.newpage()
grid.draw(
  cbind(
    rbind(ggplotGrob(p3), ggplotGrob(p4), size = "first"),
    rbind(ggplotGrob(p1), ggplotGrob(p2), size = "first"), 
    size = "first"))

网格图

我不确定这种方法是否能让您在不同的宽度中绘制p3和不同的高度中绘制p2,就像您在原始示例中一样;我通常需要一个大小相似的图形网格,并且没有必要弄清楚不同的大小。

这个答案部分基于https://dev59.com/9mQm5IYBdhLWcg3wowIF#17463184


3

这里有一个例子:

m <- matrix(c(3, 1, 0, 2), 2, byrow = T)
lay <- gglayout(m, widths = c(1, 3), heights = c(3, 1))
ggtable(p1, p2, p3, layout = lay)

您可以通过以下方式使用此功能:

install.packages('devtools')
library(devtools)
dev_mode()
install_github("ggplot2", "kohske", "cutting-edge")
library(ggplot2)

请注意,这个分支是实验性的,可能会有一些错误。 enter image description here

如果 install_github 无法正常工作,则从此处下载 zip 文件:https://github.com/kohske/ggplot2/tree/cutting-edge 并进行安装。 - kohske
谢谢kohske,我一定会研究这个。你知道这是否将成为计划于三月发布的ggplot2版本的一部分吗?由于这是我正在开发的软件包,我宁愿不依赖于ggplot2的开发版本。 - jbryer

0
使用align.plots方法解决问题时,在布局调用中指定respect=TRUE
grid_layout <- grid.layout(nrow=2, ncol=2, widths=c(1,2), heights=c(2,1), respect=TRUE)

对于那些对此感兴趣的人,这个图形是使用即将推出的multilevelPSA包生成的。 - jbryer

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接