首页 > 解决方案 > ggplot、ggsave 和 coord_map/quickmap:如何保存大型空间对象并获得正确的投影?

问题描述

我有一个较大的折线 shapefile(巴伐利亚河流,可以在此处访问),我想通过 ggplot 绘制和保存它。这可以通过例如以下代码轻松完成:

library(ggplot2)
library(rgdal)
library(sp)
library(rgeos)

riv <- readOGR(paste0(getwd(),"\\rivers_bavaria","rivers_bavaria"))
riv1 <- subset(riv,WDM=="1310"|WDM=="1320")
riv2 <- subset(riv,WDM=="1330")

p <- ggplot() +
  geom_line(data=riv1, aes(x=long, y=lat, group=group), color="dodgerblue", size=1) +
  geom_line(data=riv2, aes(x=long, y=lat, group=group), color="dodgerblue")

ggsave(paste0(getwd(),"\\riv.tiff",p,device="tiff",units="cm",dpi=300)

由于文件很大,这并不完全有效,但它确实有效。但是,如果没有进一步指定纵横比或投影,输出文件的尺寸由绘图窗口定义 - 这对于地图来说是不可取的。这可以通过使用来解决coord_quickmap()

p1 <- ggplot() +
  geom_line(data=riv1, aes(x=long, y=lat, group=group), color="dodgerblue", size=1) +
  geom_line(data=riv2, aes(x=long, y=lat, group=group), color="dodgerblue") +
  coord_quickmap()
p1

不幸的是,投影完全关闭。我已经尝试过coord_map()获得更好的结果,但由于文件很大,它需要很长时间,因此不是一个现实的选择。通过简化折线gLinemerge()会产生一个小得多的对象,但不能由 ggplot 处理,因为它是一个 SpatialLines 对象。使用fortify()data.frame()强制将其转换为对 ggplot 友好的数据框格式也会产生Error: ggplot2 doesn't know how to deal with data of class SpatialLines.

因此,我正在拼命寻找一种工作流程,它允许我使用 ggplot 绘制和保存这种高质量的空间数据。任何建议将不胜感激!

标签: rplotggplot2gissp

解决方案


这是一个快速演练sf。我建议使用sf小插图和文档来查看任何功能的更多详细信息。我首先使用 将 shapefile 作为sf对象读取sf::st_read,然后过滤、变异和选择与您相同的对象dplyr以获得较小版本的形状。

library(tidyverse)
library(sf)

rivers_sf <- st_read("rivers_bavaria/rivers_bavaria.shp") %>%
  filter(WDM %in% c("1310", "1320", "1330")) %>%
  mutate(name2 = ifelse(WDM == "1330", "river 2", "river 1")) %>%
  select(name2, NAM, geometry)

该对象非常大,绘制起来会很慢,所以我通过按名称合并几何图形来简化它,然后使用st_simplify. 还有rmapshaper::ms_simplify,它使用 Mapshaper ,我更喜欢它来更好地控制你保留多少信息。然后为了展示 CRS 转换,我从德国 的Spatial Reference中选择了一个投影。

riv_simple <- rivers_sf %>%
  group_by(name2, NAM) %>%
  summarise(geometry = st_union(geometry)) %>%
  ungroup() %>%
  st_simplify(preserveTopology = T, dTolerance = 1e6) %>%
  st_transform(31493)

ggplot2GitHub 上的开发版具有geom_sf绘制不同类型sf对象的功能。要获取此版本,请运行devtools::install_github("tidyverse/ggplot2").

geom_sf有一些怪癖,并且与其他geoms的工作方式略有不同,但它非常通用。我相信它会包含在下一个 CRAN 版本中。geom_sf有对应stat_sf的和coord_sf。默认情况下,它绘制刻度线;要关闭它们,请添加coord_sf(ndiscr = F).

ggplot(riv_simple) +
  geom_sf(aes(size = name2), color = "dodgerblue", show.legend = "line") +
  scale_size_manual(values = c("river 1" = 1, "river 2" = 0.5)) +
  theme_minimal() +
  coord_sf(ndiscr = F)

在此处输入图像描述

希望能帮助您入门!


推荐阅读