如何在地图上标记个别状态,而在分区级别标记其他状态

时间:2017-06-21 14:29:47

标签: sf ggrepel

我设法制作了一张地图,但是我需要为状态(第2级)添加一个标签,包括细分(第3级),而不是标记每个细分(仅适用于此状态)。在数据“newpak”中,行641-664对应于此状态,是否有任何方法只能在此状态上放置一个名称。

library(dplyr)
library(raster)
library(sf)
library(tidyverse)
library(ggrepel)
devtools::install_github("tidyverse/ggplot2", force = TRUE)
library(ggplot2)

pak <- getData("GADM",country="PAK",level=3) 

pak <- st_as_sf(pak) %>% 
  mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]]))

ggplot(pak) + geom_sf() + geom_text(aes(label = NAME_3, x = lon, y = lat), size = 2)

ind <- getData("GADM",country="IND",level=3) 

ind <- st_as_sf(ind) %>% 
  mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]]))

jnk <- subset(ind, OBJECTID >= 641 & OBJECTID <= 664 )

newpak <- rbind(pak, jnk)


regionalValues <- runif(165)  # Simulate a value for each region between 0 and 1

ggplot(newpak) + geom_sf(aes(fill = regionalValues)) + geom_text(aes(label = NAME_3, x = lon, y = lat), size = 2)

enter image description here

1 个答案:

答案 0 :(得分:11)

这是使用sf包的完整解决方案。

library(raster)
library(sf)
library(tidyverse)

# downlaod PAK data and convert to sf
pak <- getData("GADM",country="PAK",level=3) %>% 
  st_as_sf()

# download IND data, convert to sf, filter out 
# desired area, and add NAME_3 label
jnk <- getData("GADM",country="IND",level=3) %>%
  st_as_sf() %>%
  filter(OBJECTID %>% between(641, 664)) %>%
  group_by(NAME_0) %>%
  summarize() %>%
  mutate(NAME_3 = "Put desired region name here")


regionalValues <- runif(142)  # Simulate a value for each region between 0 and 1

# combine the two dataframes, find the center for each
# region, and the plot with ggplot
pak %>% 
  select(NAME_0, NAME_3, geometry) %>%
  rbind(jnk) %>% 
  mutate(
    lon = map_dbl(geometry, ~st_centroid(.x)[[1]]),
    lat = map_dbl(geometry, ~st_centroid(.x)[[2]])
    ) %>%
  ggplot() + 
  geom_sf(aes(fill = regionalValues)) +
  geom_text(aes(label = NAME_3, x = lon, y = lat), size = 2) +
  scale_fill_distiller(palette = "Spectral")

一些注意事项:

  • 我使用sf::filter代替raster::subset来获取IND数据的所需子集,因为我觉得它是更惯用的tidyverse代码。

  • 要将区域与sf合并,您可以使用group_by按公共组对不同区域进行分组,然后只需拨打summarize即可。这是我在上面的解决方案中使用的方法。 sf包中还有其他功能可以实现类似的结果。它们是st_combinest_union

  • 使用st_centroid绘制区域标签不一定是找到区域标签的好位置的最佳方法。我用它是因为它最方便。您可以尝试其他方法,包括手动放置标签。

  • 我将填充调色板更改为发散的调色板,因为我认为它更清楚地显示了一个区域与下一个区域之间的差异。您可以使用RColorBrewer::display.brewer.all()

  • 查看一些可用的调色板