Search code examples
rggplot2ggmap

Add easily readable scale bar to ggmap (using ggsn package?)


I am working on inserting a scale bar into some of my maps. I work with ggmaps and am currently using the ggsn package to insert a scale bar. However, this scale bar is extremely difficult to read on the types of maps I'm working with (see map below). I would like to either (a) find a way to make it easier to read, (b) have the scale bar be outside the map boundaries, or (c) use a different package that allows for easier customization.

Essentially, my code looks something like this. This example should be easily reproducible.

map <- get_map(location = c(146, 15), zoom = 8,
               maptype = “satellite”, source = "google") 

Map <- ggmap(map)

Map + ggsn::scalebar(x.min = 144.5, x.max = 147.5,
           y.min = 13.5, y.max = 16.5, 
           dist = 50, dd2km = TRUE, model = 'WGS84')

And produces a map like the one below, where the scale bar in the bottom right corner is hard to read.

ggmap with scalebar

Any ideas? Thank you so much!


Solution

  • The development version of scalebar at Github has new arguments, st.color and box.fill, which allow better customisation of the bar.

    Install that version using:

    devtools::install_github('oswaldosantos/ggsn')
    

    And then use e.g.:

    ggmap(Map) + 
      my_scalebar(x.min = 144.5, x.max = 147.5,
                y.min = 13.5,  y.max = 16.5,
                dist = 50, dd2km = TRUE, model = 'WGS84',
                box.fill = c("yellow", "white), st.color = "white")
    

    enter image description here

    OLDER ANSWER

    I wrote this answer on how to modify the function before discovering the newer version.

    I think the best approach here is to modify the scalebar function.

    First, you need to load the ggsn package and edit the function:

    library(ggsn)
    my_scalebar <- edit(scalebar)
    

    This should pop up an editor. Modify the top of the function so that it looks like this:

    function (data = NULL, location = "bottomright", dist, height = 0.02, 
      st.dist = 0.02, st.bottom = TRUE, st.size = 5, dd2km = NULL, 
      model, x.min, x.max, y.min, y.max, anchor = NULL, facet.var = NULL, 
      facet.lev = NULL, box2_fill = "yellow", legend_color = "white")
    {
      require(maptools)
    

    We added 3 things:

    • an argument box2_fill with default value = "yellow"
    • an argument legend_color with default value = "white"
    • require maptools because the function uses gcDestination() from that package

    Next, look for the line that begins gg.box2 and alter it to use the value for box2_fill:

      gg.box2 <- geom_polygon(data = box2, aes(x, y), fill = box2_fill, 
        color = "black")
    

    Then, edit the section near the bottom of the function to use the value for legend_color:

    else {
        gg.legend <- annotate("text", label = paste0(legend[, 
          "text"], "km"), x = x.st.pos, y = st.dist, size = st.size,
          color = legend_color)
      }
    

    Saving will close the editor and save the new function my_scalebar to your work space.

    Now you can use the new function. You can either supply values to the new arguments box2_fill = and legend_color =, or just try the defaults:

    ggmap(Map) + 
      my_scalebar(x.min = 144.5, x.max = 147.5,
                y.min = 13.5,  y.max = 16.5,
                dist = 50, dd2km = TRUE, model = 'WGS84')
    

    And if you think your edits are useful, you could suggest them to the package developer using a pull request at Github. NOTE: it looks like the developer has started to address this issue, since the Github version of scalebar has new box.fill and st.color arguments.