Search code examples
rggplot2r-sfggmap

Is there a way to pass piped data through ggmap like you can with ggplot to the geoms?


While exploring with ggplot a common workflow is to do some data manipulation and then pipe directly into a ggplot(). When you do that, all of that manipulation flows nicely through the ggplot into the geoms with no variables needed. Like so:

data %>%
  filter(route %in% c('01','08','15')) %>%
  ggplot() + 
  geom_sf() + 
  geom_sf_text(aes(label=route))

If however you want to use a ggmap() for a nice background, then there doesn't appear to be a way to use the piped workflow. You have to save the manipulations to a variable first, which isn't a huge deal, but would love to know if there's a way to avoid it.

This doesn't work:

background = get_stamenmap(....) # somewhat irrelevant to the question

data %>%
  filter(route %in% c('01','08','15')) %>%
  ggmap(background) + 
  geom_sf() + 
  geom_sf_text(aes(label=route))

Thought maybe trying to force the data into ggmap() might help but it doesn't

background = get_stamenmap(....) # somewhat irrelevant to the question

data %>%
  filter(route %in% c('01','08','15')) %>%
  ggmap(background, data=.) + 
  geom_sf() + 
  geom_sf_text(aes(label=route))

Or maybe there's some other way to combine ggplot() and ggmap() to accomplish it? I know I can save off the manipulated data as a variable and then hard-code that into each geom_sf() layer, but it's just not as convenient and thought I might be missing something simple.


Solution

  • The magrittr::%>% infix operator expects to pass the data as the first argument of the first expression in a +-chain as you have here. Unfortunately, you want to pass it to one of the not-first expressions. You can use a {-block.

    library(ggmap)
    library(ggplot2)
    library(dplyr) # for %>%, could do magrittr as well
    
    ### from ?get_stamenmap
    bbox <- c(left = -97.1268, bottom = 31.536245, right = -97.099334, top = 31.559652)
    background <- get_stamenmap(bbox, zoom = 14)
    
    ### from my brain
    set.seed(42)
    dat <- data.frame(x=runif(4, bbox[1], bbox[3]), y=runif(4, bbox[2], bbox[4]), lbl = sample(LETTERS, 4))
    dat
    #           x        y lbl
    # 1 -97.10167 31.55127   Q
    # 2 -97.10106 31.54840   O
    # 3 -97.11894 31.55349   X
    # 4 -97.10399 31.53940   G
    
    dat %>% {
      ggmap(background) +
      geom_point(aes(x, y), data = .) +
      geom_text(aes(x, y, label = lbl), data = ., color = "red",
                hjust = 0, vjust = 0)
    }
    

    sample ggmap with additional data piped in