【问题标题】:How to add extra legend to a map plot in ggplot2 based on column entries?如何根据列条目向 ggplot2 中的地图图添加额外的图例?
【发布时间】:2015-02-14 07:28:49
【问题描述】:

数据:Data

代码:

palette = brewer.pal(11,"RdYlGn")    # ColorBrewewr.org spectral palette, 11 colors
ggmap_byscen   = ggplot(wmap_byscen.df[wmap_byscen.df$variable !=c("AVG") &
                                     wmap_byscen.df$ID_1 !=c("0"),], aes(x=long, y=lat, group=group))
ggmap_byscen   = ggmap_byscen + geom_polygon(aes(fill=value)) + facet_wrap(~ variable)
ggmap_byscen   = ggmap_byscen + geom_path(colour="grey50", size=.1)
ggmap_byscen   = ggmap_byscen + geom_text(aes(x=c.long, y=c.lat, label=ID_1),size=5)
ggmap_byscen   = ggmap_byscen + scale_fill_gradientn(name="% Change",colours=palette)
ggmap_byscen   = ggmap_byscen + coord_fixed(xlim = longlimits, ylim = latlimits)
ggmap_byscen   = ggmap_byscen + scale_y_continuous(breaks=seq(-60,90,30), labels=c("60ºS","30ºS","0º","30ºN","60ºN","90ºN"))
ggmap_byscen   = ggmap_byscen + scale_x_continuous(breaks=seq(-180,180,45), labels=c("180ºW","135ºW","90ºW","45ºW","0º","45ºE","90ºE","135ºE","180ºE"))
ggmap_byscen   = ggmap_byscen + labs(x="",y="",title="Average yield impacts across all crops across\nby climate scenarios (% change)")
ggmap_byscen   = ggmap_byscen + theme(plot.title=element_text(size=rel(2), hjust=0.5, vjust=1.5, face="bold"),
                                  legend.text=element_text(size=17),
                                  legend.position="left",legend.text=element_text(size=rel(1.3)),
                                  legend.title=element_text(size=rel(1.4), hjust=0.5, vjust=1),
                                  panel.background = element_rect(fill = "white", colour = "gray95"),
                                  strip.text = element_text(size=18),
                                  axis.text.x = element_text(size=16),
                                  axis.text.y = element_text(size=16))
ggmap_byscen

结果:

问题:我希望在数据框中添加一个由“标签”列定义的附加图例,以识别地图上的区域。最好,我希望图例位于多面图下方。我已经看到了一些示例,其中可以将表条目添加为单独的图,然后将两者合并。我不知道如何为我的情况制作它。

任何帮助都会很棒,谢谢。

【问题讨论】:

  • 您似乎没有定义longlimitslatlimits

标签: r ggplot2 maps


【解决方案1】:

正如@jlhoward 提到的,longlimitslatlimits 没有定义。因此,我决定将coord_fixed(xlim = longlimits, ylim = latlimits) 部分从这个答案中删除。我的解决方法有效,但我确信有更好的方法来解决这个问题。挑战在于以一种能够很好地呈现数据的方式创建另一个图例。如果您在geom_text 中使用colour,您可以创建另一个图例,但您最终会看到字母表,即图例中灰色框中的a。所以,我决定在aes 中使用geom_pointalpha = 0 以及colour。这样,您就有了一个带有 ID 名称的新图例,但您在地图上看不到任何点。然后,我使用annotate 分配地图上的数字。感谢@jlhoward,我创建了一个小数据框,这是annotate() 所必需的。如果您使用原始数据框,R 会尝试写入 4000 次左右的文本。在主题部分,我添加了legend.key = element_rect(fill = NA),以便删除图例中的灰色方块。我把图形的高度和宽度做得很小,这样我就可以把它贴在这里了。所以它看起来并不那么好。但是,如果您指定较大的数字,则该数字会更好看。

library(dplyr)
library(ggplot2)

wmap_byscen.df <- read.csv("mydata.csv", header = T)

mydf <- wmap_byscen.df[wmap_byscen.df$variable != c("AVG") &
        wmap_byscen.df$ID_1 != c("0"),]

### This is for annotate()

mydf2 <- select(mydf, c.long, c.lat, ID_1, ID_name) %>%
         distinct()

### Color setting

palette = brewer.pal(11,"RdYlGn")


ggplot(mydf, aes(x = long, y = lat, group = group)) +
geom_polygon(aes(fill = value)) + 
facet_wrap(~ variable) +
geom_path(colour = "grey50", size = .1) +
geom_point(aes(x = c.long, y = c.lat, color=factor(ID_name, levels=unique(ID_name)), label = ID_1), size = 1, alpha = 0) +
annotate("text", x = mydf2$c.long, y = mydf2$c.lat, label = mydf2$ID_1) +
scale_fill_gradientn(name = "% Change",colours = palette) +
scale_color_discrete(name = "Regions") +
#coord_fixed(xlim = longlimits, ylim = latlimits) +
scale_y_continuous(breaks = seq(-60,90,30), labels = c("60ºS","30ºS","0º","30ºN","60ºN","90ºN")) +
scale_x_continuous(breaks = seq(-180,180,45), labels = c("180ºW","135ºW","90ºW","45ºW","0º","45ºE","90ºE","135ºE","180ºE")) +
labs(x = "",y = "",title = "Average yield impacts across all crops across\nby climate scenarios (% change)") +
theme(plot.title = element_text(size = rel(2), hjust = 0.5, vjust = 1.5, face = "bold"),
      legend.text = element_text(size = 8),
      legend.position = "bottom",
      legend.text = element_text(size = rel(1.3)),
      legend.title = element_text(size = rel(1.4), hjust = 0.5, vjust = 1),
      panel.background = element_rect(fill = "white", colour = "gray95"),
      strip.text = element_text(size = 18),
      axis.text.x = element_text(size = 16),
      axis.text.y = element_text(size = 16),
      legend.key = element_rect(fill = NA)) +
guides(col = guide_legend(nrow = 3, byrow = TRUE)) 

【讨论】:

  • 如果您在对geom_point(...) 的调用中设置alpha=0,那么这些点就会消失,而size=... 无关紧要。
  • 另外,当你以这种方式使用annotate(...)时,你正在为mydf的每一行绘制一个标签,因此每个标签同时被绘制了大约4000次地点。这就是为什么它运行得如此缓慢。 OP 对geom_text(...) 的使用也有同样的问题。你真的应该用 16 个标签和坐标创建一个单独的数据框。
  • 最后,请注意图例是按字母顺序排列的,而不是按数字排列的(例如,1、10、11、12、...而不是 1、2、3、...)这是因为方式ggplot 管理因素。您可以在对geom_point(aes(...)) 的调用中使用color=factor(ID_name, levels=unique(ID_name)) 并在底部对guide_legend(...) 的调用中使用byrow=TRUE 来解决此问题。
  • @jlhoward 非常感谢您的进一步说明。是的,我注意到代码很慢,但我不认为为什么会这样。至于图例的顺序,我只是留下了它,因为它稍后会使用因子修复。但似乎这个操作比我想象的要多。谢谢你的建议。鉴于所有这些,我今天有一些很好的修改。 :)
  • @iouraich 我考虑过。我在 SO 上找到了一个帖子,但这似乎让事情变得有点复杂。看看this post
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-01
  • 1970-01-01
相关资源
最近更新 更多