使用R中的sf将美学映射到LINESTRING几何体。

5
新近推出的 R 包 sf 使得在 R 中处理地理数据变得非常容易,ggplot2 的开发版本中也新增了一个 geom_sf() 图层,用于绘制 sf 风格的地理数据。
在 sf 数据处理范例中,是否可以将 ggplot 美学映射到 LINESTRING 几何图形上?
例如,在标准 ggplot 中,可以使用此数据通过调整军队路径的大小来重现 Minard 在 1812 年拿破仑大军的幸存者的著名图表。
# Install the dev version of ggplot2 for geom_sf()
# devtools::install_github("tidyverse/ggplot2")
library(tidyverse)

troops <- read_csv("https://gist.githubusercontent.com/andrewheiss/69b9dffb7cca392eb7f9bdf56789140f/raw/3e2a48635ae44837955765b5e7747c429b0b5d71/troops.csv")

ggplot(troops) +
  geom_path(aes(x = long, y = lat, color = direction, 
                group = group, size = survivors),
            lineend = "round")

我们可以通过创建一个新的geometry列,将这些部队数据作为sf对象来处理,如下所示:
library(sf)
#> Linking to GEOS 3.6.1, GDAL 2.1.3, proj.4 4.9.3

troops_with_geometry <- troops %>%
  st_as_sf(coords = c("long", "lat"))

head(troops_with_geometry)
#> Simple feature collection with 6 features and 3 fields
#> geometry type:  POINT
#> dimension:      XY
#> bbox:           xmin: 24 ymin: 54.5 xmax: 28 ymax: 55
#> epsg (SRID):    NA
#> proj4string:    NA
#> # A tibble: 6 x 4
#>   survivors direction group          geometry
#>       <int>     <chr> <int>  <simple_feature>
#> 1    340000         A     1 <POINT (24 54.9)>
#> 2    340000         A     1 <POINT (24.5 55)>
#> 3    340000         A     1 <POINT (25.5 ...>
#> 4    320000         A     1 <POINT (26 54.7)>
#> 5    300000         A     1 <POINT (27 54.8)>
#> 6    280000         A     1 <POINT (28 54.9)>

如果我们使用geom_sf绘制,ggplot将使用点:
ggplot(troops_with_geometry) +
  geom_sf(aes(color = direction, group = group))

我们可以通过分组、汇总和转换来为每个组和方向创建线字符串。
troops_lines <- troops_with_geometry %>%
  group_by(direction, group) %>% 
  summarize() %>% 
  st_cast("LINESTRING")

head(troops_lines)
#> Simple feature collection with 6 features and 2 fields
#> geometry type:  LINESTRING
#> dimension:      XY
#> bbox:           xmin: 24 ymin: 54.1 xmax: 37.7 ymax: 55.8
#> epsg (SRID):    NA
#> proj4string:    NA
#>   direction group                       geometry
#> 1         A     1 LINESTRING (24 54.9, 24.5 5...
#> 2         A     2 LINESTRING (24 55.1, 24.5 5...
#> 3         A     3 LINESTRING (24 55.2, 24.5 5...
#> 4         R     1 LINESTRING (24.1 54.4, 24.2...
#> 5         R     2 LINESTRING (28.3 54.2, 28.5...
#> 6         R     3 LINESTRING (24.1 54.4, 24.2...

ggplot可以绘制这六条连接线并正确着色。
ggplot(troops_lines) +
  geom_sf(aes(color = direction, group = group))

然而,幸存者数据现在已经消失了,没有办法将大小美学映射到新的线路上。是否有一种方法将其他美学(如大小)与基于sfLINESTRING数据相关联?换句话说,是否有一种方法使用geom_sf()和sf地理数据处理范例重新创建ggplot(...) + geom_path(aes(x = long, y = lat, size = something))

哦,没错。你需要开发版本 :) - Andrew
1个回答

4

enter image description here您需要从每组点对中创建一个线串。由于我不知道如何给线条圆形端点,因此结果可能不太美观。

# within each group repeat each point 
# then slice the first and last out and 
# add a variable called linegroup, which provides grouping for start and endpoints of each line
troops %<>% group_by(group) %>%
  slice(rep(1:n(), each = 2)) %>%
  slice(-c(1, n())) %>%
  mutate(linegroup = lapply(1:(n()/2), function(x) rep(x, 2)) %>% unlist) %>% 
  ungroup

# create linestring sf object by summarizing the points, 
# grab the last survivor and direction value of each group (i.e. the 'endpoint' value)
troops_line <- st_as_sf(troops, coords = c("long", "lat"), crs = 4326) %>%
  group_by(group, linegroup) %>%
  summarise(survivors = last(survivors), direction = last(direction), do_union = FALSE) %>%
  st_cast("LINESTRING")

gp <- ggplot(troops_line) +
  geom_sf(aes(color = direction, size = survivors), show.legend = "line") 

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