将ggplot2的几何图形添加到简单特征绘图中

6

sf包似乎比sp更加用户友好,用来处理空间数据。例如,如果我有一组纬度/经度坐标,我可以很容易地在ggplot2的开发版本中绘制:

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

# generate some data
set.seed(123)

y = rnorm(10, mean=40, sd=20)
x = rnorm(10, mean=-100, sd=30)

# collect to data.frame
xy = data.frame(x=x,y=y)

# create sf object
xy.sf = sf::st_as_sf(xy, coords=c("x", "y"), crs=4269)

# plot points
ggplot(data=xy.sf) + geom_sf()
ggplot2::geom_sf 函数知道 xy.sf 对象的几何形状是一组点,因此我不需要调用 ggplot2::geom_point() 等函数。
但是,假设我想基于这组点添加另一个几何图形。
例如,如果我想生成一个轮廓层来显示点的聚集情况,我可以使用 ggplot2::geom_density2dggplot2::stat_density2d,如此答案此答案中所建议的那样。
然而,以下代码:
ggplot(data=xy.sf) +
    geom_sf() +
    geom_density2d(data=xy.sf, aes(x=x,y=y,colour=..level..))

生成了以下图像:

测试等高线地图

请注意,等高线似乎具有反转的坐标!

我尝试调整上面的代码,但无法使其正常工作。我意识到sf包是相当新的,但这张地图非常接近正确!有什么想法吗?

编辑:忘记添加会话信息

> sessionInfo()
R version 3.4.0 (2017-04-21)
Platform: x86_64-w64-mingw32/x64 (64-bit)
Running under: Windows 7 x64 (build 7601) Service Pack 1

Matrix products: default

locale:
[1] LC_COLLATE=English_United States.1252 
[2] LC_CTYPE=English_United States.1252   
[3] LC_MONETARY=English_United States.1252
[4] LC_NUMERIC=C                          
[5] LC_TIME=English_United States.1252    

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggplot2_2.2.1.9000 sf_0.4-3          

loaded via a namespace (and not attached):
 [1] Rcpp_0.12.9       magrittr_1.5      maps_3.1.1        units_0.4-4      
 [5] MASS_7.3-47       munsell_0.4.3     geosphere_1.5-5   colorspace_1.3-2 
[9] lattice_0.20-35   rjson_0.2.15      jpeg_0.1-8        rlang_0.1.1      
[13] stringr_1.2.0     udunits2_0.13     plyr_1.8.4        tools_3.4.0      
[17] rgdal_1.2-5       grid_3.4.0        gtable_0.2.0      png_0.1-7        
[21] DBI_0.5-1         ggthemes_3.3.0    lazyeval_0.2.0    assertthat_0.1   
[25] digest_0.6.12     tibble_1.3.1      ggmap_2.6.1       reshape2_1.4.2   
[29] mapproj_1.2-4     labeling_0.3      sp_1.2-4          stringi_1.1.2    
[33] compiler_3.4.0    RgoogleMaps_1.4.1 scales_0.4.1      proto_1.0.0

我得到了“正确”的图形,但在OSX Sierra、R 3.4.0、ggplot2_2.2.1.9000和sf_0.4-3上无法重现这种行为。(sf的最新版本是0.5-1,但它需要GDAL 2.0或更高版本,我还没有安装。) - eipi10
我也得到了正确的绘图,使用 sf 0.5.1。 - GGamba
刚升级到GDAL 2.2.0和sf 0.5.1。仍然能够正确地绘制图形。但是,如果我明确地反转坐标,即geom_density2d(aes(x=y, y=x, colour=..level..)),则我可以重现你的图形。 - eipi10
谢谢,@eipi10!! 我重新加载了示例,现在它可以工作了。原来我创建向量xyyx,这对于data.frame没有关系,但对于geom_density2d有影响。这解决了我在“真实”数据中遇到的问题,其中我一直收到错误x not found。那是因为geom_density2d没有从xy.sf获取x,而是从向量x本身获取!当我删除x时,我会得到相同的错误。 - juan
1个回答

2

为了日后参考,我想把我的研究结果发表一下:

事实证明,在 geom_sf 之后添加一层图层(例如,geom_density2d),不会继承应用于 geom_sf 的映射美学。

请注意,以下操作可以正常工作:

ggplot(data=xy.sf, aes(x=x, y=y)) +
    geom_sf() +
    geom_density2d(aes(colour=..level..))

但只有因为x,y作为独立于xy.sf对象而存在。

因此,以下代码会抛出错误:

rm(x,y)
ggplot(data=xy.sf, aes(x=x, y=y)) +
    geom_sf() +
    geom_density2d(aes(colour=..level..))

在 FUN(X[[i]], ...) 中出现错误:对象 'x' 未找到

当然,这可以在文档中找到!

"geom_sf使用一个独特的美学:geometry...与其他美学不同,geometry永远不会从图表中继承。"

所以我发现的解决方法是使用x,y对象本身或sf对象的纯data.frame版本;例如,geom_density2d(data=xy, aes(x,y,colour=..level..))


将来参考,请确保 sf 对象具有相同的 CRS(即使用 st_transform() 进行转换),然后将几何列使用 mutate()extract() 转换为纬度-经度或东北平面坐标系,然后将其作为 x 和 y 输入到 aes() 中。 - grad student

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