6

我设法制作了一张地图,但是我需要为包含细分(级别 3)的州(级别 2)添加一个标签,而不是标记每个细分(仅针对此州)。在数据“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)

在此处输入图像描述

4

1 回答 1

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()

于 2017-06-21T15:04:47.467 回答