如何根据列条目在ggplot2中为地图绘图添加额外的图例?

时间:2014-12-16 03:16:51

标签: r ggplot2 maps

数据: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

结果:Map

问题:我希望添加一个由"标签"列定义的额外图例。在数据框中标识地图上的区域。最好是,我希望图例位于分面地图下方。我见过一些例子,可以将表条目作为单独的图添加,然后将两者合并。我无法弄清楚如何为我的案子做好准备。

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

1 个答案:

答案 0 :(得分:4)

正如@jlhoward所述,longlimitslatlimits未定义。因此,我决定将coord_fixed(xlim = longlimits, ylim = latlimits)部分留在这个答案中。我的解决方法有效,但我确信有更好的方法可以解决这个问题。挑战在于以一种能够很好地呈现数据的方式创建另一个传奇。如果您在colour中使用geom_text,则可以创建另一个图例,但最终会看到字母,即图例中的灰色框。所以,我决定在geom_point中使用alpha = 0 colour以及aes。通过这种方式,您有一个带有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)) 

enter image description here