Mapping different states with geom_sf using facet wrap and scales free
Asked Answered
V

1

19

First, I am aware of this answer : Mapping different states in R using facet wrap
But I work with object of library sf.
It seems that facet_wrap(scales = "free") is not available for objects plotted with geom_sf in ggplot2. I get this message:

Erreur : Free scales are only supported with coord_cartesian() and coord_flip()

Is there any option I have missed ?
Anyone has solve the problem without being forced to use cowplot (or any other gridarrange)?

Indeed, here is an example. I would like to show the different French regions separately in facets but with their own x/y limits.

The result without scales = "free"

Scales are calculated with the extent of the entire map.

FRA <- raster::getData(name = "GADM", country = "FRA", level = 1)
FRA_sf <- st_as_sf(FRA)

g <- ggplot(FRA_sf) +
  geom_sf() +
  facet_wrap(~NAME_1)

facet regions with geom_sf

The result using cowplot

I need to use a list of ggplots and can then combine them. This is the targeted output. It is cleaner. But I also want a clean way to add a legend. (I know may have a common legend like in this other SO question : facet wrap distorts state maps in R)

g <- purrr::map(FRA_sf$NAME_1,
           function(x) {
             ggplot() +
               geom_sf(data = filter(FRA_sf, NAME_1 == x)) +
               guides(fill = FALSE) +
               ggtitle(x)
           })

g2 <- cowplot::plot_grid(plotlist = g)

facet regions with geom_sf and cowplot

Veilleux answered 6/12, 2017 at 15:57 Comment(3)
Does it distort even if you pre-project the polygons?Hintz
There is no distortion here. The "distort" word comes from the title of the other referenced question on SO. I rephrase the sentence to make it clear.Stealer
@SébastienRochette were you able to get a answer to this question. I am having this exact problem.Bugeye
K
10

I know you are looking for a solution using ggplot2, but I found the tmap package could be a choice depends on your need. The syntax of tmap is similar to ggplot2, it can also take sf object. Take your FRA_sf as an example, we can do something like this.

library(tmap)

tm_shape(FRA_sf) +
  tm_borders() +
  tm_facets(by = "NAME_1")

enter image description here

Or we can use geom_spatial from the ggspatial package, but geom_spatial only takes Spatial* object.

library(ggplot2)
library(ggspatial)

ggplot() +
  geom_spatial(FRA) + # FRA is a SpatialPolygonsDataFrame object
  facet_wrap(~NAME_1, scales = "free")

enter image description here

Kistler answered 6/12, 2017 at 16:59 Comment(3)
I now have a reason to try tmap ! Let's add this on my list.Stealer
Although I admire the work in tmap, I am dependent on geom_sf() and this is not the answer to "Mapping different states with geom_sf", so should not be the accepted answer. It's a great answer in terms of outside the box thinking, but it does not answer the question of the OP. That the OP is satisfied with this answer makes it unnecessarily complicated.Valora
@MSBerends Your interpretation of what is qualified as an accepted answer and how to upvote/downvote an answer seems to be different than most of the SO users, but I respect your opinion. Good luck on your future endeavor.Kistler

© 2022 - 2024 — McMap. All rights reserved.