在ggplot2中,我如何添加额外的图例?

22

我正在尝试使用来自不同数据框的数据构建ggplot2地图。

library(maptools)

xx <- readShapePoly(system.file("shapes/sids.shp", package="maptools")[1], IDvar="FIPSNO", proj4string=CRS("+proj=longlat +ellps=clrk66"))

xx.sub1 <- subset(xx, xx$FIPSNO < 37010)
xx.sub2 <- subset(xx, xx$FIPSNO > 37010)

xx.sub1@data$id <- rownames(xx.sub1@data)
xx.sub1.points <- fortify(xx.sub1, region="id")
xx.sub1.df = plyr::join(xx.sub1.points, xx.sub1@data, by="id")

xx.sub2@data$id <- rownames(xx.sub2@data)
xx.sub2.points <- fortify(xx.sub2, region="id")
xx.sub2.df = plyr::join(xx.sub2.points, xx.sub2@data, by="id")

ggplot(xx.sub2.df) + 
  aes(long, lat, fill = (SID79/BIR79)*1000, group = group) + 
  geom_polygon() + geom_path(color="grey80") +
  coord_equal() + 
  scale_fill_gradientn(colours = RColorBrewer::brewer.pal(7, "YlOrBr")) +
  geom_polygon(data = xx.sub1.df, fill = "grey50") + 
  geom_path(data = xx.sub1.df, color="grey80") +
  labs(fill = "Mapped value", title = "Title")

到目前为止,一切都按照预期工作并且我得到了一个漂亮的地图:

enter image description here

然而,我想要做出的改变是为来自xx.sub1.df的数据添加单独的图例 - 因为所有多边形都只被灰色填充,所以我希望它会是一个额外条目。

我该如何实现这个?


4
可以提供一个可重现的例子吗?解决这个问题的经典方式是合并数据集,包括一个因子变量来标识每个数据集来自哪个原始数据框,然后使用一个美学元素(在您的情况下为填充),您可以查看scales包,看看是否有其他方法。 - Ben Bolker
@BenBolker 收到。已添加示例。我知道把所有内容放在一个数据框中会更容易。然而,我经常使用不同层次的数据(可能是因为我的GIS背景),如果要合并这些数据将会非常麻烦。在这个特定的例子中,我需要快速选择几个多边形并对它们进行“突出显示”或“遮罩”。 - radek
请添加一个 dput 数据,这样就可以用更新的热图回答你的问题了。我猜测:(1) 你只使用了 xx.sub2 的两列,(2) 如果州在 xx.sub1 中出现,则它们会呈灰色。因此,连接似乎并不那么麻烦。你可以在 xx.sub2 中简单地添加一个因子,以表示在 xx.sub1 中存在的条目,并且也许可以使用 scale_fill_manual 来调整图例中的颜色。 - G Chalancon
@GChalancon 我正在使用 maptools 包中的示例数据,希望能够重现一个示例(我相信不再需要使用 dput 了?)。至于第1点和第2点 - 对于玩具示例来说,所有有效选项。然而,对于真实情况,数据集更加复杂,您的解决方案将更难实现。因此,我希望能够在没有连接的情况下处理“独立”的数据框,以实现这一目标。 - radek
1
哦,我之前没有尝试加载数据,是我的错误。主要的困难在于你想要映射两个使用相同美学类型(geom_polygon)的不同比例尺。据我所知,在ggplot2中这是不可能的,但是我有一个建议:使用不同的注释(例如geom_text)来标记“灰色”区域如何?这将给您带来2个图例,但我知道这可能并不令人满意。还有一件事:在实际情况下,xx.sub1.df的区域是否可能与xx.sub2.df重叠? - G Chalancon
@GChalancon 感谢您的更新。只要图例包括灰色多边形,我完全可以接受任何方法。geom_text 实际上可能是一个好主意,所以如果您使用这种方法成功地实现了什么,请告诉我! - radek
1个回答

32

我不完全确定这是否是您想要的,但这是我理解问题的方法。如果我们将一些未使用的geom与来自xx.sub1.df的任何数据进行映射,但在图表上使其不可见,我们仍然可以获得该geom的图例。这里我使用了geom_point,但您也可以选择其他方式。

p <- ggplot(xx.sub2.df) + 
  aes(long, lat, fill = (SID79/BIR79)*1000, group = group) + 
  geom_polygon() + geom_path(color="grey80") +
  coord_equal() + 
  scale_fill_gradientn(colours = brewer.pal(7, "YlOrBr")) +
  geom_polygon(data = xx.sub1.df, fill = "grey50") + 
  geom_path(data = xx.sub1.df, color="grey80") +
  labs(fill = "Mapped value", title = "Title")

#Now we add geom_point() setting shape as NA, but the colour as "grey50", so the 
#legend will be displaying the right colour

p2 <- p + geom_point(data = xx.sub1.df, aes(size="xx.sub1", shape = NA), colour = "grey50")

现在我们只需要改变图例上点的大小和形状,以及更改图例的名称(感谢@DizisElferts在此之前展示了这一点earlier)。

p2 + guides(size=guide_legend("Source", override.aes=list(shape=15, size = 10)))

这里输入图片描述

当然,您可以更改标签的工作方式或其他内容,以突出您想要展示的内容。

如果这不是您想要的,请让我知道!


太好了!在我看来,似乎没有其他解决方法,只能添加一个新的美学元素(这里是“geom_point”),可以添加图例。我不知道“shape=NA”,所以这真的很有用。 - G Chalancon

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