【问题标题】:Justification of multiple legends in ggmap/ggplot2ggmap/ggplot2 中多个图例的对齐方式
【发布时间】:2012-11-17 00:42:11
【问题描述】:

我正在尝试制作一个带有两个表示形状和颜色的图例(下例中的“类型”和“组织”)的地图,并插入图例。我可以放置图例,但我希望它们左对齐,以便它们的左边缘对齐。除了相对于彼此居中之外,我无法使它们成为任何东西:

require(ggplot2)
require(ggmap)
require(grid)
require(mapproj)

data <- data.frame(Org=rep(c("ABCDEFG","HIJKLMNOP","QRSTUVWX"),4)
                   , Type=rep(c("Y","Z"),6), Lat=runif(12,48,54.5)
                   , Long=runif(12,-133.5,-122.5))

osmMap <- get_map(location=c(-134,47.5,-122,55), source = 'osm')

points <- geom_jitter(data=data, aes(Long, Lat, shape=Type
                                     , colour=Org))

legend <- theme(legend.justification=c(0,0), legend.position=c(0,0)
                , legend.margin=unit(0,"lines"), legend.box="vertical"
                , legend.key.size=unit(1,"lines"), legend.text.align=0
                , legend.title.align=0)

ggmap(osmMap) + points + legend

【问题讨论】:

  • 这不是一个直接的答案,但您可以通过使用 format 使它们的大小相等来作弊。在您的数据声明后尝试data$Type &lt;- format(data$Type, width=17) 并重新运行您的代码。
  • 这是一个巧妙的技巧,谢谢。我会在星期一试一试

标签: r ggplot2 ggmap r-grid


【解决方案1】:

这个选项现在在 ggplot2 0.9.3.1 中可用,使用

ggmap(osmMap) + points + legend + theme(legend.box.just = "left")

旧的手动解决方案:

这里有一个解决方案:

require(gtable)
require(ggplot2)
require(ggmap)
require(grid)
require(mapproj)

# Original data
data <- data.frame(Org=rep(c("ABCDEFG","HIJKLMNOP","QRSTUVWX"),4),
                   Type=rep(c("Y","Z"),6), Lat=runif(12,48,54.5),
                   Long=runif(12,-133.5,-122.5))
osmMap <- get_map(location=c(-134,47.5,-122,55), source = 'google')
points <- geom_jitter(data=data, aes(Long, Lat, shape=Type, colour=Org))
legend <- theme(legend.justification=c(0,0), legend.position=c(0,0),
                legend.margin=unit(0,"lines"), legend.box="vertical",
                legend.key.size=unit(1,"lines"), legend.text.align=0,
                legend.title.align=0)

# Data transformation
p <- ggmap(osmMap) + points + legend
data <- ggplot_build(p)
gtable <- ggplot_gtable(data)

# Determining index of legends table
lbox <- which(sapply(gtable$grobs, paste) == "gtable[guide-box]")
# Each legend has several parts, wdth contains total widths for each legend
wdth <- with(gtable$grobs[[lbox]], c(sum(as.vector(grobs[[1]]$widths)), 
                                     sum(as.vector(grobs[[2]]$widths))))
# Determining narrower legend
id <- which.min(wdth)
# Adding a new empty column of abs(diff(wdth)) mm width on the right of 
# the smaller legend box
gtable$grobs[[lbox]]$grobs[[id]] <- gtable_add_cols(
                                      gtable$grobs[[lbox]]$grobs[[id]], 
                                      unit(abs(diff(wdth)), "mm"))
# Plotting
grid.draw(gtable)

这不依赖于TypeOrg。然而,仅仅拥有两个以上的传说是不够的。 另外,如果您进行一些更改以更改 grobs(图形对象)列表,您可能需要将 grobs[[8]] 更改为 grobs[[i]] 其中 i 是您的图例的位置,请参阅 gtable$grobs并寻找TableGrob (5 x 3) "guide-box": 2 grobs

编辑: 1. 自动检测哪个 grob 是图例表,即在修改绘图的其他部分后无需更改任何内容。 2. 更改了宽度差异的计算,现在代码在有任何两个图例时都应该可以工作,即在更复杂的情况下也是如此,例如:

【讨论】:

  • 谢谢@Julius - 这很好用,让我对使用 gtable 有了一些了解,这是我以前没有真正探索过的。
  • 我无法重现此示例。我从哪里获得osmMap?我假设这是一些数据集。
  • @FaheemMitha,是的,这是来自问题的数据。我已将其添加到我的答案中,并将source = 'osm' 更改为source = 'google',因为前者至少目前不起作用。
  • 谢谢,朱利叶斯。感谢您的快速回复。
猜你喜欢
  • 1970-01-01
  • 2023-03-21
  • 2016-06-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-20
  • 2015-08-11
相关资源
最近更新 更多