对ggplot区域地图进行边缘对齐(图例标题不同)

10

我正试图使用这种方法来对齐4个ggplot区域地图的左右边缘,但是我无法做到。

原始绘图:

library(ggplot2); library(gridExtra)
crimes <- data.frame(state = tolower(rownames(USArrests)), USArrests)
states_map <- map_data("state")
plot1 <- ggplot(crimes, aes(map_id = state)) +
    geom_map(aes(fill = Murder), map = states_map) +
    expand_limits(x = states_map$long, y = states_map$lat) + 
    scale_fill_gradient(low="white", high="darkgreen", name="Really Long Name 1")


plot2 <- plot1 + scale_fill_gradient(name="Really Long Name 2 and then some")
plot3 <- plot1 + scale_fill_gradient(name="Short 3") 
plot4 <- plot1 + scale_fill_gradient(name="Really Long Name 4")

grid.arrange(plot1, plot3, plot2, plot4, ncol = 2)

尝试对齐图形边缘(将得到相同的结果):

p1 <- ggplotGrob(plot1)
p2 <- ggplotGrob(plot2)
p3 <- ggplotGrob(plot3)
p4 <- ggplotGrob(plot4)

maxWidth <- grid::unit.pmax(p1$widths[2:3], p2$widths[2:3], p3$widths[2:3], p4$widths[2:3])
p1$widths[2:3] <- as.list(maxWidth)
p2$widths[2:3] <- as.list(maxWidth)
p3$widths[2:3] <- as.list(maxWidth)
p4$widths[2:3] <- as.list(maxWidth)

grid.arrange(p1, p3, p2, p4, ncol = 2) 

在此输入图片描述

附注:假设我需要使用网格排列,并且图例实际上不是同一比例,因此facet_grid不适用等。


1
如果仅图例标题有问题,您是否考虑将其水平放置在顶部或底部?即 plot1 + theme(legend.position='bottom', legend.direction='horizontal') - MrGumble
根据您发布的链接中的评论建议,您可能想要在整个过程中使用widths[2:5]来包括图例以比较单位。请注意,这将导致与@kohske的第一个答案相同的图例居中,因为指南grob会在分配的视口中心自我居中。 - baptiste
我尝试了 widths[2:5],但结果非常奇怪。 - Tyler Rinker
我撒谎了,但这个程序确实有效。@Baptise,你能否将这作为未来搜索者的答案提供吗? - Tyler Rinker
我已经编辑了原始帖子,所以我宁愿将你的问题关闭为重复 :) - baptiste
这可能是明智的,但如果他不转移,我们将失去Kohske的答案。 - Tyler Rinker
2个回答

9

以下是一个例子:

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

输入图像描述


更新

这是一种糟糕的黑客方法,因此我不建议使用。 很可能将来无法使用。

gt <- cbind(rbind(p1, p2, size="last"), rbind(p3, p4, size="last"), size = "first")
for (i in which(gt$layout$name == "guide-box")) {
  gt$grobs[[i]] <- gt$grobs[[i]]$grobs[[1]]
}
grid.draw(gt)

enter image description here


2
不错的解决方案。我想知道是否可能将图例对齐,以便仅增加绘图右侧的空间。 - Sven Hohenstein
糟糕,gtgt <- cbind(rbind(p1, p2, size="last"), rbind(p3, p4, size="last"), size = "first")) - kohske
那么,让我试着理解一下:gt$grobs[[i]] 是一个 gtable,但它实际上只是用另一个 gtable 包装了一下真正的 grobs,子 gtable 在其容器内居中显示? - baptiste
@baptiste 没错,gtablegtable 生成了一个绘图时的包装视口。这是一个不好的 hack,现在 Paul 实现了新的钩子 grid::makeContext。也许重写 gtable 的某些部分会更好。你可以在这里找到我们的努力:http://rpubs.com/kohske/815。 - kohske
是的,很不幸,我忘记了去年的许多讨论,并且似乎自那时以来一直保持着现状。顺便说一下,Paul Murrell已经使用他的新函数重写了gtable(请参见他在github上的分支),但我不确定这对现有指南部分意味着什么。 - baptiste
请注意,这是我将在未来的博客文章中发布的一部分。如果有人对此图表(特别是最终图表)有任何意见,请发送电子邮件至tyler.rinker@gmail.com - Tyler Rinker

2
使用cowplot包:

使用cowplot包:

library(cowplot)
plot_grid(plot1, plot3, plot2, plot4, ncol = 2, align = "v")

enter image description here


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