Search code examples
rggplot2gismap-projectionsr-sf

Error changing projection via coord_sf for geom_sf and geom_point at the same time


I want to plot a map with geom_sf and add points from another dataset, then change the projection. For example:

# setup
library(ggplot2)
library(sf)
nc <- sf::st_read(system.file("shape/nc.shp", package = "sf"), quiet = TRUE)
point <- data.frame(id = "hi", lat = 36, long = -80) # point inside NC

# can change projection
ggplot() +
  geom_sf(data = nc) +
  coord_sf(crs = st_crs(3347))

# can add a point
ggplot() +
  geom_sf(data = nc) +
  geom_point(data = point, aes(x = long, y = lat))

# but can't do both: see plot attached
ggplot() +
  geom_sf(data = nc) +
  geom_point(data = point, aes(x = long, y = lat)) +
  coord_sf(crs = st_crs(3347))

See plot below. The other two plots look normal; the last one converts the NC map okay, but projects the coordinate close way off its original lat/long:

Map of NC and one weird coordinate.

I've tried various combinations of converting the points to sf objects first, changing their projections to be consistent before calling ggplot, all to no avail so far. Any advice would help; PS I'm pretty new to GIS.

Session info (tried updating R and sf/ggplot2 packages):

> sessionInfo()
R version 3.5.2 (2018-12-20)
Platform: x86_64-apple-darwin15.6.0 (64-bit)
Running under: macOS Mojave 10.14.2

Matrix products: default
BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
LAPACK: /Library/Frameworks/R.framework/Versions/3.5/Resources/lib/libRlapack.dylib

locale:
[1] en_CA.UTF-8/en_CA.UTF-8/en_CA.UTF-8/C/en_CA.UTF-8/en_CA.UTF-8

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

other attached packages:
[1] sf_0.7-2      ggplot2_3.1.0

loaded via a namespace (and not attached):
 [1] Rcpp_1.0.0       rstudioapi_0.8   bindr_0.1.1      magrittr_1.5    
 [5] units_0.6-2      tidyselect_0.2.5 munsell_0.5.0    colorspace_1.3-2
 [9] R6_2.3.0         rlang_0.3.1      plyr_1.8.4       dplyr_0.7.8     
[13] tools_3.5.2      grid_3.5.2       gtable_0.2.0     e1071_1.7-0     
[17] DBI_1.0.0        withr_2.1.2      class_7.3-15     lazyeval_0.2.1  
[21] assertthat_0.2.0 tibble_2.0.0     crayon_1.3.4     bindrcpp_0.2.2  
[25] purrr_0.2.5      glue_1.3.0       labeling_0.3     compiler_3.5.2  
[29] pillar_1.3.1     scales_1.0.0     classInt_0.3-1   pkgconfig_2.0.2 

Solution

  • You can convert point to an sf object and set the crs (perhaps you forgot to set the crs?). This is because coord_sf can convert layers to common projections but they need to be sf objects for it to know how to do so.

    ### add this below creation of point object
    point <- st_as_sf(point, coords = c("long", "lat"), crs = 4326)
    
    ggplot() +
      geom_sf(data = nc) +
      geom_sf(data = point) +
      coord_sf(crs = st_crs(3347))
    

    enter image description here