r-spatial/sf

Setting lims alters the shape of geom_sf

Closed this issue · 8 comments

Describe the bug

Hi, I'm making maps of Russia using geom_sf, but the height/width ratio seems off. Is there a way to maintain the shape as it appears in a global context?

To Reproduce

library(sf)
#> Linking to GEOS 3.13.0, GDAL 3.9.2, PROJ 9.5.0; sf_use_s2() is TRUE
library(rnaturalearth)
library(ggplot2)
russia <- ne_countries(country = "russia", returnclass = "sf")
russia |>
  st_bbox(russia)
#>       xmin       ymin       xmax       ymax 
#> -180.00000   41.15142  180.00000   81.25040

ggplot() +
  geom_sf(data = russia) +
  coord_sf(crs = 4326, expand = F)

ggplot() +
  geom_sf(data = russia) +
  coord_sf(crs = 4326, expand = F) +
  ylim(-90, 90)

Created on 2024-10-23 with reprex v2.1.1

Here are two things you could try:

ortho = st_crs("+proj=ortho +lon_0=90 +lat_0=60")                                                                           |  /tmp/Nvim-R-edzer/Rsource-430273:4:0: unexpected end of input                 
ggplot() +                                                                                                                  |2:   geom_sf(data = st_transform(russia, "+proj=eqc +lon_0=-90") +              
  geom_sf(data = st_transform(russia, ortho))                                                                               |3:   coord_sf(crs = 4326, expand = F)                                           
eqc = st_crs("+proj=eqc +lon_0=90")                                                                                         |  ^                                                                             
ggplot() +                                                                                                                  |> NvimR.chunk(echo=TRUE)                                                        
  geom_sf(data = st_transform(russia, eqc)) 

Thanks @edzer Russia is just one example, but more generally, it seems that QGIS can preserve the shape as it appears in a global context. I’m curious if geom_sf offers a similar option without changing the projection.

What exactly do you mean by global context? Could you share the QGIS image?

By “global context”, I mean placing a regional map inside a global map. Here is the example of USA.

library(sf)
#> Linking to GEOS 3.13.0, GDAL 3.9.2, PROJ 9.5.0; sf_use_s2() is TRUE
library(rnaturalearth)
library(ggplot2)

world <- ne_countries(returnclass = "sf")
usa <- world |> dplyr::filter(name == "United States of America")

ggplot() +
  geom_sf(data = world)

ggsave("fig-world.png", width = 10, height = 5)

ggplot() +
  geom_sf(data = usa, color = "red", fill = NA) +
  theme_void()+
  theme(plot.background = element_rect(color = 'red'))

ggsave("fig-usa.png", width = 7, height = 5)

If I overlay two figures, the shapes of USA don't match up.
image

However, in QGIS, the shapes of USA remain consistent regardless of the context.
image

Here is the map of USA alone.
image

I think that if you add for instance +coord_sf(crs = st_crs("+proj=eqc")) to the two ggplot() commands, you get png files that match when overlayed.

@edzer Yes exactly. Could you briefly explain why?
I'm closing this issue.

Could you briefly explain why?

Because for unprojected data a projection needs to be chosen, and a pragmatic decision is to choose equidistant rectangular (map lon/lat linearly to x/y), while choosing an (map) aspect ratio that has unit scale (1 m North = 1 m East) at the center of the map. This aspect ratio is chosen at the center of the map, and the center of the us is different from the center of the world.