ggplot не отображает точки линий из объекта sf - PullRequest
1 голос
/ 25 мая 2020

Учитывая следующие данные:

library(tidyverse)
library(sf)
df <- structure(list(geometry = c("LINESTRING (-85.76 38.34, -85.72 38.38)", 
                                  "LINESTRING (-85.46 38.76, -85.42 38.76)", 
                                  "LINESTRING (-85.89 38.31, -85.89 38.31)"
), var1 = c(4, 5, 6
), var2 = c(1, 2, 3
)), row.names = c(NA, -3L), class = c("tbl_df", "tbl", "data.frame"
))
df
df_sf <- sf::st_as_sf( df, wkt = "geometry" )
# Simple feature collection with 3 features and 2 fields
# geometry type:  LINESTRING
# dimension:      XY
# bbox:           xmin: -85.89 ymin: 38.31 xmax: -85.42 ymax: 38.76
# CRS:            NA
# # A tibble: 3 x 3
#                       geometry  var1  var2
#                   <LINESTRING> <dbl> <dbl>
# 1 (-85.76 38.34, -85.72 38.38)     4     1
# 2 (-85.46 38.76, -85.42 38.76)     5     2
# 3 (-85.89 38.31, -85.89 38.31)     6     3

Мы можем использовать plot для построения данных, включая LINESTRING, который имеет две точки в одном месте (строка = 3):

plot(st_geometry(df_sf), lwd = 10)

, что дает:

enter image description here

но когда мы строим его, используя ggplot, точка опускается:

ggplot() +
  geom_sf(data = df_sf, lwd = 8)

enter image description here

Без ручного извлечения местоположений, содержащих только точку, есть ли быстрый способ указать ggplot их построить? Я вижу, что эти точки технически не являются линией, поскольку между ними нет расстояния, но plot может их поднять. Этот вопрос кажется связанным, но немного другим, мои LINESTRING уже созданы.

спасибо

Ответы [ 2 ]

2 голосов
/ 01 июля 2020

Это одна из тех ситуаций, в которых смайлы головного стола могут пригодиться:

ggplot() +
  geom_sf(data = df_sf, lwd = 8, lineend = "round")

plot

From the package's виньетка на эстетике c спецификации , окончание строки по умолчанию - "приклад ", который останавливается точно в конечной точке линии (так что линия нулевой длины не будет ничего показывать), в то время как" круглая "альтернатива выходит за пределы конечной точки:

иллюстрация

TL; DR : Линия нулевой длины не выпала. Мы просто не могли этого увидеть.

1 голос
/ 25 мая 2020

Я думаю, что вы можете решить эту проблему, если вы измените геометрию LINESTRING, длина которой равна 0, и преобразуйте их в ТОЧКИ. Например:

# packages
library(ggplot2)
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1

# data
df <- structure(
  list(
    geometry = c(
      "LINESTRING (-85.76 38.34, -85.72 38.38)",
      "LINESTRING (-85.46 38.76, -85.42 38.76)", 
      "LINESTRING (-85.89 38.31, -85.89 38.31)"
      ), 
    var1 = c(4, 5, 6), 
    var2 = c(1, 2, 3)
    ), 
  row.names = c(NA, -3L), 
  class = c("tbl_df", "tbl", "data.frame")
)
df_sf <- st_as_sf( df, wkt = "geometry" )

# Rebuild the geometry column in such a way that the zero-length LINESTRINGS are
# actually POINTS:
new_df_sf_geometry <- st_geometry(df_sf)
idx <- which(st_length(new_df_sf_geometry) == 0)
for (i in idx) {
  new_df_sf_geometry[i] <- unique(st_cast(new_df_sf_geometry[i], "POINT"))
}

# This is the result
new_df_sf_geometry
#> Geometry set for 3 features 
#> geometry type:  GEOMETRY
#> dimension:      XY
#> bbox:           xmin: -85.89 ymin: 38.31 xmax: -85.42 ymax: 38.76
#> CRS:            NA
#> LINESTRING (-85.76 38.34, -85.72 38.38)
#> LINESTRING (-85.46 38.76, -85.42 38.76)
#> POINT (-85.89 38.31)

# Replace the geometry
st_geometry(df_sf) <- new_df_sf_geometry

# Plot
ggplot(df_sf) + 
  geom_sf(size = 3)

Создано 25.05.2020 с помощью пакета REPEX (v0.3.0)

Если вам нужно, вы также можете использовать более сложные подходы, чем for-l oop, например purrr::map_if.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...