ggplot、ggsave & coord_map/quickmap:如何保存大型空间对象并获得正确的投影?
ggplot, ggsave & coord_map/quickmap: how to save large spatial objects and get the projection right?
我有一个较大的折线 shapefile(巴伐利亚河流,可以访问 here),我想通过 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)
由于文件较大,这不是很有效,但它确实有效。但是,如果没有进一步指定纵横比或投影,输出文件的尺寸由绘图 window 定义——这对于地图来说是不可取的。这可以通过使用 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 以高质量绘制和保存此类空间数据。任何建议将不胜感激!
这是 sf
的快速演练。我推荐 sf
插图和文档以查看任何功能的更多详细信息。我首先使用 sf::st_read
将 shapefile 作为 sf
对象读取,然后像在 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)
GitHub 上 ggplot2
的开发版本有一个函数 geom_sf
用于绘制不同类型的 sf
对象。要获取此版本,运行 devtools::install_github("tidyverse/ggplot2")
.
geom_sf
有一些怪癖,与其他 geom 的工作方式略有不同,但它的用途非常广泛。我相信它会包含在下一个 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)
希望对您有所帮助!
我有一个较大的折线 shapefile(巴伐利亚河流,可以访问 here),我想通过 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)
由于文件较大,这不是很有效,但它确实有效。但是,如果没有进一步指定纵横比或投影,输出文件的尺寸由绘图 window 定义——这对于地图来说是不可取的。这可以通过使用 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 以高质量绘制和保存此类空间数据。任何建议将不胜感激!
这是 sf
的快速演练。我推荐 sf
插图和文档以查看任何功能的更多详细信息。我首先使用 sf::st_read
将 shapefile 作为 sf
对象读取,然后像在 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)
GitHub 上 ggplot2
的开发版本有一个函数 geom_sf
用于绘制不同类型的 sf
对象。要获取此版本,运行 devtools::install_github("tidyverse/ggplot2")
.
geom_sf
有一些怪癖,与其他 geom 的工作方式略有不同,但它的用途非常广泛。我相信它会包含在下一个 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)
希望对您有所帮助!