Search code examples
rggplot2gisggspatial

ggspatial::geom_spatial_path() function not working as intended


I'm currently studying the basics of GIS with R at this link. I'm at Vector Data > Lines section and I'm experiencing something that looks like a bug when trying to plot some LINESTRING objects with ggspatial package.

Below my code:

library(ggplot2)
library(ggspatial)
library(patchwork)

#### 3 LINESTRING OBJECTS
l1 <- matrix(c(10,10,10,12,14,16,15,10), ncol = 2, byrow = T) |> sf::st_linestring()
l2 <- matrix(c(14,16,10,19), ncol = 2, byrow = T) |> sf::st_linestring()
l3 <- matrix(c(10,12,5,13), ncol = 2, byrow = T) |> sf::st_linestring()

#### SF OBJECT WITH GEOMETRIES, CRS AND ATTRIBUTES
line_sfc <- sf::st_sfc(l1,l2,l3, crs = 4326)
l_att <- data.frame(road_name = c("Viale Garibaldi", "Via Voltaire", "Viale Pasolini"), 
                    speed_limit = c(75, 50, 30))
line_sf <- sf::st_sf(l_att, line_sfc)
line_sf

## Simple feature collection with 3 features and 2 fields
## Geometry type: LINESTRING
## Dimension:     XY
## Bounding box:  xmin: 5 ymin: 10 xmax: 15 ymax: 19
## Geodetic CRS:  WGS 84
##         road_name speed_limit                       line_sfc
## 1 Viale Garibaldi          75 LINESTRING (10 10, 10 12, 1...
## 2    Via Voltaire          50      LINESTRING (14 16, 10 19)
## 3  Viale Pasolini          30       LINESTRING (10 12, 5 13)

Now, if I use base plot() function as shown in the GIS crash course I linked above, the plot works as intended.

plot(line_sf)

enter image description here

But when I use ggplot2 and ggspatial packages, a 4th line is added to speed_limit plot, and I really don't know why.

sp_df <- ggspatial::df_spatial(line_sf)

p1 <- ggplot2::ggplot(sp_df, aes(x,y)) +
  ggspatial::geom_spatial_path(aes(colour = road_name)) +
  ggspatial::coord_sf(crs = 4326) +
  xlab("lon") +
  ylab("lat") +
  ggtitle("road_name")


p2 <- ggplot2::ggplot(sp_df, aes(x,y)) +
  ggspatial::geom_spatial_path(aes(color = speed_limit)) +
  ggspatial::coord_sf(crs = 4326) +
  xlab("lon") +
  ylab("lat") +
  ggtitle("speed_limit")

p1 / p2

enter image description here

What's the problem here? Where that additional line comes from? Am I doing something wrong or is this a bug? Any help is appreciated.


Solution

  • You seem to be doing things the hard way, since ggplot has excellent sf support. Rather than loading an extra dependency, using extra code and converting to a data frame, why not simply plot the sf object directly?

    p1 <- ggplot(line_sf) +
      geom_sf(aes(geometry = line_sfc, color = road_name)) +
      labs(title = "road_name", x = "lon", y = "lat") 
    
    p2 <- ggplot(line_sf) +
      geom_sf(aes(geometry = line_sfc, color = speed_limit)) +
      labs(title = "speed_limit", x = "lon", y = "lat")
    
    p1 / p2
    

    enter image description here

    If you have good reasons for converting to a data frame, the alternative is to group the second plot by road name so that adjacent groups aren't connected:

    sp_df <- ggspatial::df_spatial(line_sf)
    
    p1 <- ggplot2::ggplot(sp_df, aes(x,y)) +
      ggspatial::geom_spatial_path(aes(colour = road_name)) +
      ggspatial::coord_sf(crs = 4326) +
      xlab("lon") +
      ylab("lat") +
      ggtitle("road_name")
    
    ggplot2::ggplot(sp_df, aes(x,y)) +
      ggspatial::geom_spatial_path(aes(color = speed_limit, group = road_name)) +
      ggspatial::coord_sf(crs = 4326) +
      xlab("lon") +
      ylab("lat") +
      ggtitle("speed_limit")
    
    p1 / p2
    

    enter image description here