ggplot - 在地图上创建边框叠加层

时间:2018-03-26 17:24:08

标签: r ggplot2 maps choropleth

所以我正在尝试使用基于自定义变量的边框创建佛罗里达州县级地图。我在此处添加了一个旧版本的地图

基本上,该地图显示了佛罗里达州的一个地区细分,媒体市场以粗体黑线边界标出。我能够轻松地绘制区域。我希望增加的是在媒体市场变量" MMarket"定义的区域外围的更大胆的黑线边界,类似于上面显示的地图。填充变量将是Region,媒体市场边界轮廓将使用MMarket定义。以下是数据的读入和强化方法:

#read in data
fl_data <- read_csv("Data for Mapping.csv")

#read in shapefiles
flcounties1 <- readOGR(dsn =".",layer = "Florida Counties")

#Fortify based on county name
counties.points <- fortify(flcounties1, region = "NAME")
counties.points$id <- toupper(counties.points$id)

#Merge plotting data and geospatial dataframe 
merged <- merge(counties.points, merged_data, by.x="id", by.y="County", all.x=TRUE)

fl_data对象包含要映射的数据(包括媒体市场变量),shapefile数据读入flcounties1。以下是我使用的合并数据框的示例:

 head(merged %>% select(id:group, Region, MMarket))
       id      long      lat order  hole piece     group    Region     MMarket
1 ALACHUA -82.65855 29.83014     1 FALSE     1 Alachua.1 Panhandle Gainesville
2 ALACHUA -82.65551 29.82969     2 FALSE     1 Alachua.1 Panhandle Gainesville
3 ALACHUA -82.65456 29.82905     3 FALSE     1 Alachua.1 Panhandle Gainesville
4 ALACHUA -82.65367 29.82694     4 FALSE     1 Alachua.1 Panhandle Gainesville
5 ALACHUA -82.65211 29.82563     5 FALSE     1 Alachua.1 Panhandle Gainesville
6 ALACHUA -82.64915 29.82648     6 FALSE     1 Alachua.1 Panhandle Gainesville

我可以使用以下代码轻松获取区域变量的地图:(here is a picture of the map)

ggplot() +
  # county polygons
  geom_polygon(data = merged, aes(fill = Region,
                                  x = long,
                                  y = lat,
                                  group = group)) +
  # county outline
  geom_path(data = merged, aes(x = long, y = lat, group = group), 
            color = "black", size = 1) +
  coord_equal() +
  # add the previously defined basic theme
  theme_map() +
  labs(x = NULL, y = NULL, 
       title = "Florida: Regions by County") +
  scale_fill_brewer(palette = "Set3",
                    direction = 1,
                    drop = FALSE,
                    guide = guide_legend(direction = "vertical",
                                         title.hjust = 0,
                                         title.vjust = 1,
                                         barheight = 30,
                                         label.position = "right",
                                         reverse = T,
                                         label.hjust = 0))

2 个答案:

答案 0 :(得分:1)

可能有更好的方法,但我的解决方法是强化您需要绘制的所有维度的数据。

在你的情况下,我会创建你的县和MMarkets的强化数据集,并像你一样绘制地图,但是添加一层geom_polygon没有填充,所以只绘制边框。

merged_counties   <- fortify(merged, region = "id")
merged_MMarket    <- fortify(merged, region = "MMarket")

然后

ggplot() +
  # county polygons
  geom_polygon(data = merged_counties, aes(fill = Region,
                                  x = long,
                                  y = lat,
                                  group = group)) +
# here comes the difference
geom_polygon(data = merged_MMarket, aes(x = long,
                                  y = lat,
                                  group = group),
                                  fill = NA, size = 0.2) +
  # county outline
  geom_path(data = merged, aes(x = long, y = lat, group = group), 
            color = "black", size = 1) +
  coord_equal() +
  # add the previously defined basic theme
  theme_map() +
  labs(x = NULL, y = NULL, 
       title = "Florida: Regions by County") +
  scale_fill_brewer(palette = "Set3",
                    direction = 1,
                    drop = FALSE,
                    guide = guide_legend(direction = "vertical",
                                         title.hjust = 0,
                                         title.vjust = 1,
                                         barheight = 30,
                                         label.position = "right",
                                         reverse = T,
                                         label.hjust = 0))

使用巴西形状文件的示例

brasil      <- readOGR(dsn = "path to shape file", layer = "the file")
brasilUF    <- fortify(brasil, region = "ID_UF")
brasilRG    <- fortify(brasil, region = "REGIAO")

ggplot() +
  geom_polygon(data = brasilUF, aes(x = long, y = lat, group = group), fill = NA, color = 'black')  +
  geom_polygon(data = brasilRG, aes(x = long, y = lat, group = group), fill = NA, color = 'black', size = 2) +
  theme(rect            = element_blank(), # drop everything and keep only maps and legend
        line            = element_blank(),
        axis.text.x     = element_blank(),
        axis.text.y     = element_blank(),
        axis.title.x    = element_blank()
  ) +
  labs(x = NULL, y = NULL) +
  coord_map()

enter image description here

答案 1 :(得分:1)

以下是您想要进入sf的简单示例。这取决于从github获得ggplot2的开发版本,因为尚未将sf层添加到CRAN版本中。由于我没有你的shapefile,我只是使用tigris下载康涅狄格州的县细分shapefile,然后将其转换为一个简单的功能对象。

# download the shapefile I'll work with
ct_shp <- tigris::county_subdivisions(state = "09", cb = T)
# convert SpatialPolygonsDataFrame to sf
ct_sf <- st_as_sf(ct_shp)

如果我想按原样绘制这些城镇,我可以使用ggplotgeom_sf

ggplot(ct_sf) +
    geom_sf(fill = "gray95", color = "gray50", size = 0.5) +
    # these 2 lines just clean up appearance
    theme_void() +
    coord_sf(ndiscr = F)

函数st_union为您提供了基于另一个变量的多个特征的并集。我将根据他们的县FIPS代码联合城镇,这是COUNTYFP列。 sf个函数适合dplyr个管道,非常棒。

所以这个:

ct_sf %>% 
    group_by(COUNTYFP) %>% 
    summarise(geometry = st_union(.))

会给我一个sf对象,其中所有城镇都已合并到他们的县。我可以将这两个结合起来得到第一个geom_sf图层中的城镇地图,然后在第二层动态为县进行联合:

ggplot(ct_sf) +
    geom_sf(fill = "gray95", color = "gray50", size = 0.5) +
    geom_sf(fill = "transparent", color = "gray20", size = 1, data = . %>% group_by(COUNTYFP) %>% summarise(geometry = st_union(.))) +
    theme_void() +
    coord_sf(ndiscr = F)

这让我知道了:

ct map with sf

不再fortify