Search code examples
rggplot2usmap

Add points to usmap with ggplot in r


I was able to create a US map with this tutorial. When I tried to add additional points to it they all ended up in South Dakota, no matter what I input for data.

library(ggplot2)
library(usmap)
testData <- data.frame(LATITUDE = 20.31557, LONGITUDE = -102.42547)
p <- plot_usmap( regions = "state") 
p + geom_point(data = testData, aes(x = LONGITUDE, y = LATITUDE), color = "red")

Solution

  • That's an "interesting" package that doesn't have much value-add over the blog post code the underlying shapefiles were generated from (yet the package author did not see fit to credit the author of the blog post in the package DESCRIPTION, just a tack-on to the end of a README).

    One thing the author also did not see fit to do is provide support for anything but choropleths. Your problem is that the map is in one coordinate system and your points are in another.

    If you can use non-CRAN packages, albersusa (which was around for a while before the usamap author did the copypasta package) provides the necessary glue:

    library(albersusa) # https://gitlab.com/hrbrmstr/albersusa / https://github.com/hrbrmstr/albersusa
    library(ggplot2)
    library(sp)
    

    Get the US map pre-projected:

    us <- usa_composite(proj = "aeqd")
    

    We'll use built-in "state.center" data to get some points

    states_centers <- as.data.frame(state.center)
    states_centers$name <- state.name
    

    However, if you look up the help on state.center you'll see that they don't provide legit coords for Alaska & Hawaii, we we can't use them:

    states_centers <- states_centers[!(states_centers$name %in% c("Alaska", "Hawaii")),]
    

    NOTE: If you do have points in Alaska/Hawaii you need to se the 'points_elided() function in the package to modify any Alaska or Hawaii points. A longstanding TODO has been to make points_elided() support all the transforms but I almost never need to use the package outside of choropleths so it'll be TODO for a while.

    Now, make them legit coords for our map by going from straight long/lat to the projected coordinate system:

    coordinates(states_centers) <- ~x+y
    proj4string(states_centers) <- CRS(us_longlat_proj)
    states_centers <- spTransform(states_centers, CRSobj = CRS(us_aeqd_proj))
    states_centers <- as.data.frame(coordinates(states_centers))
    

    And, plot them:

    us_map <- fortify(us, region="name")
    
    ggplot() +
      geom_map(
        data = us_map, map = us_map,
        aes(x = long, y = lat, map_id = id),
        color = "#2b2b2b", size = 0.1, fill = NA
      ) +
      geom_point(
        data = states_centers, aes(x, y), size = 4, color = "steelblue"
      ) +
      coord_equal() + # the points are pre-projected
      ggthemes::theme_map()
    

    enter image description here