在 sf 对象下绘制静态基础地图

18

我想在sf对象下面绘制一个静态底图(用于打印)。当我使用ggmap时,首先出现了许多错误,然后我似乎无法弄清如何将底图链接到我的ggplot2对象与一个geom_sf

library(sf)
# devtools::install_github("tidyverse/ggplot2")
library(ggplot2)
library(ggmap) 

nc <- st_read(system.file("shape/nc.shp", package="sf"))
nc_map <- get_map(location = "North Carolina, NC", zoom = 7)

ggmap(nc_map)

nc_centers <- st_centroid(nc)

nc_centers %>%
  ggplot() +
  geom_sf(aes(color = SID79, size = BIR74),
          show.legend = "point") +
  coord_sf(datum = NA) +
  theme_minimal()

我也更喜欢使用 source = "osm" 作为样式,但这些将始终返回 '400 Bad Request'

也许还有其他好的底图包吗?


我认为leaflet是一个不错的包 - 不过我不知道你是否能够用它完成你的任务。 - niko
leaflet是用于交互式地图的,对吧?我正在寻找静态打印解决方案。 - Tdebeus
1
你可以使用 mapview::mapshot 将 leaflet 地图保存为静态文件(jpeg、png 等)。也许这符合你的需求。 - TimSalabim
3个回答

16
你可以考虑重新投影你的数据,但以下代码似乎对我有效。 关于为什么需要inherit.aes = FALSE,请参见此处,关于使用基本绘图的替代解决方案,请参见此处
library(sf)
#> Linking to GEOS 3.5.1, GDAL 2.1.3, proj.4 4.9.2
# devtools::install_github("r-lib/rlang")
library(ggplot2)
library(ggmap) 

nc <- st_read(system.file("shape/nc.shp", package="sf"))
#> Reading layer `nc' from data source `/home/gilles/R/x86_64-pc-linux-gnu-library/3.4/sf/shape/nc.shp' using driver `ESRI Shapefile'
#> Simple feature collection with 100 features and 14 fields
#> geometry type:  MULTIPOLYGON
#> dimension:      XY
#> bbox:           xmin: -84.32385 ymin: 33.88199 xmax: -75.45698 ymax: 36.58965
#> epsg (SRID):    4267
#> proj4string:    +proj=longlat +datum=NAD27 +no_defs
nc_map <- get_map(location = "North Carolina, NC", zoom = 7)
#> Map from URL : http://maps.googleapis.com/maps/api/staticmap?center=North+Carolina,+NC&zoom=7&size=640x640&scale=2&maptype=terrain&language=en-EN&sensor=false
#> Information from URL : http://maps.googleapis.com/maps/api/geocode/json?address=North%20Carolina,%20NC&sensor=false
nc_centers <- st_centroid(nc)
#> Warning in st_centroid.sfc(st_geometry(x), of_largest_polygon =
#> of_largest_polygon): st_centroid does not give correct centroids for
#> longitude/latitude data

ggmap(nc_map) +
    geom_sf(data = nc_centers, 
            aes(color = SID79, size = BIR74),
            show.legend = "point", inherit.aes = FALSE) +
    coord_sf(datum = NA) +
    theme_minimal()
#> Coordinate system already present. Adding new coordinate system, which will replace the existing one.

这段文字是由reprex包(v0.2.0)在2018年4月3日创建的。


@Gilles感谢您提供的优秀解决方案。您能否添加文本注释?我尝试了 geom_sf_label(),但似乎无法与该解决方案配合使用。 - Arihant

11

最近我一直在开发一个软件包,希望有人会觉得它很有用。使用ggmap现在需要Google Maps的API密钥,这增加了额外的烦恼。

basemapR可以通过使用边界框来设置底图的范围,让您拥有更多的灵活性。

#devtools::install_github('Chrisjb/basemapR')
library(basemapR)
library(sf)
library(ggplot2)


nc <- st_read(system.file("shape/nc.shp", package="sf"))

nc_centers <- st_centroid(nc)

# create bbox from our nc layer and expand it to include more area above/below
bbox <- expand_bbox(st_bbox(nc_centers), X = 0, Y = 150000)

ggplot() +
  base_map(bbox, increase_zoom = 2, basemap = 'google-terrain') +
  geom_sf(data = nc_centers, 
          aes(color = SID79, size = BIR74),
          show.legend = "point", inherit.aes = FALSE) +
  coord_sf(datum = NA,
           xlim = c(bbox['xmin'], bbox['xmax']),
           ylim = c(bbox['ymin'], bbox['ymax'])) +
  theme_minimal() +
  labs(caption = 'map data \uA9 2020 Google')

记得在地图的标题或其他位置引用 Google 地图

输入图片描述


10
您可以使用包ggspatial,它提供了“地图瓦片”注释层。
ggplot(nc_centers) +
    annotation_map_tile(zoom = 7) +
    geom_sf(aes(color = SID79, size = BIR74),
            show.legend = "point", inherit.aes = FALSE) +
    coord_sf(datum = NA) +
    theme_minimal()

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接