首页 > 解决方案 > 如何在ggplot中将对象图例添加到地图中

问题描述

我正在用 ggplot 制作地图,以按州显示病例数。我被要求删除阿拉斯加、夏威夷和所有其他地区,并将该信息添加到类似于显示的图例的辅助对象中。这是我正在使用的代码,下面是我需要的最终绘图的示例(只是 jpg 文件)。

all_states <- map_data("state")

# let's add some fake data about cases for disease x in some states
cases <- data.frame(region = c("arizona","arkansas", "california","colorado","illinois","idaho","new york", "ohio", "oregon", "pennsylvania", "wisconsin", 
                               "alaska", "hawaii", "puerto rico", "guam", "american samoa", "northern mariana islands","virgin islands"),
                         n = c(1, 23, 47, 30, 10, 4, 90, 11, 5, 9, 60,0,5,16,24,70,30,12))             

# Data for US map 
us.map.dat <- merge(all_states, cases, by="region", all.x=TRUE)
us.map.dat <- plyr::join(all_states, cases, by="region")

us.map.dat$n[is.na(us.map.dat$n)] <- 0
us.map.dat$brks <- cut(us.map.dat$n,
                       breaks = c(0, 0.99, 5,10,50,max.breaks),
                       labels = c("0", "1 - 5", "6 - 10", "11 - 50", "51 - 200"),
                       include.lowest = TRUE)

# Making the map for the states, except Alaska and Hawaii, and territories
p1 <- ggplot() + 
      geom_polygon(data=us.map.dat, aes(x=long, y=lat, group = group, fill=brks), colour="black") +
      scale_fill_manual(name="",values = c("0"="white","1 - 5" ="#ebf5ff","6 - 10"="#add0db","11 - 50"="#7fa6c7", "51 - 200" ="#4682B4"), drop = FALSE) +
      theme(panel.grid = element_blank(),
            panel.border = element_blank(),
            panel.background = element_blank(),
            plot.title   = element_text(colour="black", size = 14, face = "bold", hjust=0.5),
            legend.key.size = unit(1, "cm"),
            legend.text = element_text(size = 16, colour = "black"),
            legend.position = c(0.95, 0.60)) + 
      labs(fill  = "n",
           title = "", x="", y="") + 
      scale_y_continuous(breaks=c()) + 
      scale_x_continuous(breaks=c()) 
p1

这是我目前的情节

在此处输入图像描述

这就是我需要的,在盒子里展示——就像阿拉斯加、夏威夷和其他地区的传奇一样。关于如何添加这些方块以显示所有其他地区的任何想法?

休谢谢!

在此处输入图像描述

标签: rggplot2mapslegend

解决方案


这可以通过ggnewscale包定义第二个填充比例来实现。为此,我用“空”行为仅包含其名称的地区填充地图数据。这个空的 df 用于第二geom_polygon层,我在填充上映射区域,这为我们提供了想要的填充,如领土的图例:

library(ggplot2)
library(dplyr)

all_states <- map_data("state")

# let's add some fake data about cases for disease x in some states
cases <- data.frame(region = c("arizona","arkansas", "california","colorado","illinois","idaho","new york", "ohio", "oregon", "pennsylvania", "wisconsin", 
                               "alaska", "hawaii", "puerto rico", "guam", "american samoa", "northern mariana islands","virgin islands"),
                    n = c(1, 23, 47, 30, 10, 4, 90, 11, 5, 9, 60,0,5,16,24,70,30,12))             

# Data for US map 
us.map.dat <- merge(all_states, cases, by="region", all.x=TRUE)
us.map.dat <- plyr::join(all_states, cases, by="region")

max.breaks <- 100

us.map.dat$n[is.na(us.map.dat$n)] <- 0
us.map.dat$brks <- cut(us.map.dat$n,
                       breaks = c(0, 0.99, 5,10,50, max.breaks),
                       labels = c("0", "1 - 5", "6 - 10", "11 - 50", "51 - 200"),
                       include.lowest = TRUE)

# Vector of territories or abbreviations
territories <- c("AS", "GU", "MP", "VI")

df.other <- data.frame(region =  territories)

us.map.dat1 <- bind_rows(us.map.dat, df.other)

# Making the map for the states, except Alaska and Hawaii, and territories
p1 <- ggplot(mapping = aes(x=long, y=lat)) + 
  geom_polygon(data=us.map.dat, aes(group = group, fill=brks), colour="black") +
  scale_fill_manual(name="",values = c("0"="white","1 - 5" ="#ebf5ff","6 - 10"="#add0db","11 - 50"="#7fa6c7", "51 - 200" ="#4682B4"), drop = FALSE) +
  # Make territories scale
  ggnewscale::new_scale_fill() +
  geom_polygon(data = filter(us.map.dat1, region %in% territories), aes(fill = region), colour="black") +
  scale_fill_manual(name="", values = c(AS = "white", GU ="#ebf5ff", MP ="white", VI ="white"), drop = FALSE) +
  theme(panel.grid = element_blank(),
        panel.border = element_blank(),
        panel.background = element_blank(),
        plot.title   = element_text(colour="black", size = 14, face = "bold", hjust=0.5),
        legend.key.size = unit(1, "cm"),
        legend.text = element_text(size = 16, colour = "black"),
        legend.position = c(0.95, 0.60)) + 
  labs(title = "", x="", y="") + 
  scale_y_continuous(breaks=c()) + 
  scale_x_continuous(breaks=c()) 
p1

reprex 包(v0.3.0)于 2020 年 6 月 15 日创建


推荐阅读