Search code examples
rggplot2facet-gridusmap

Problem with plot_usmap package to plot in R


I want to plot my data over US map and I used plot_usmap package but it not working. this is my data:

dt<- data.frame(fips = c("CA", "AL", "NY","IA", "TX","CA", "AL", "NY","IA", "TX"),
                 value = c(25, 45, 45, 60, 75,15, 65, 75, 20, 65),
                  year=c(2000, 2000, 2000, 2000, 2000,2010, 2010, 2010, 2010, 2010))

and this is my code:

plot_usmap(data = dt, values = "value", exclude = c("AK", "HI"))+
   scale_fill_continuous(low = "white", high = "red", name = "Ele gen (EJ)", label = scales::comma)+ facet_grid("year")

and this the final map:

enter image description here


Solution

  • While plot_usmap makes it easy to draw a quick map I think that in your case building the map from scratch using ggplot2 is the way to go.

    To this end you could first get the raw map data via us_map and merge your data to the map data.

    However, as your data contains multiple years but only some states we have to "complete" the dataset to include observations for each pair of year and state. Otherwise faceting by year will not work. To this end I first split your data by year, merge the single year data to the map data, use tidyr::fill to fill up the year column and finally bind the datasets by row:

    dt <- data.frame(fips = c("CA", "AL", "NY","IA", "TX","CA", "AL", "NY","IA", "TX"),
                    value = c(25, 45, 45, 60, 75,15, 65, 75, 20, 65),
                    year=c(2000, 2000, 2000, 2000, 2000,2010, 2010, 2010, 2010, 2010))
    
    library(usmap)
    library(ggplot2)
    library(dplyr)
    
    # Map data
    states <- us_map(exclude = c("AK", "HI"))
    
    # Split, join, bind
    states_data <- split(dt, dt$year) |> 
      lapply(function(x) left_join(states, x, by = c("abbr" = "fips"))) |> 
      lapply(function(x) tidyr::fill(x, year, .direction = "downup")) |> 
      bind_rows() |> 
      arrange(year, group, order)
    
    ggplot(states_data, aes(x, y, fill = value, group = group)) +
      geom_polygon() +
      scale_fill_continuous(low = "white", high = "red", name = "Ele gen (EJ)", label = scales::comma) +
      facet_grid(~year) +
      coord_equal() +
      ggthemes::theme_map() +
      theme(legend.position = "bottom")
    

    EDIT For your real data with data for all states the data preparation is much easier:

    # Join and arrange
    states_data <- left_join(states, dt, by = c("abbr" = "fips")) |> 
      arrange(emission, growth, group, order)
    
    ggplot(states_data, aes(x, y, fill = value, group = group)) +
      geom_polygon() +
      scale_fill_continuous(low = "white", high = "red", name = "Ele gen (EJ)", label = scales::comma) +
      facet_grid(emission~growth) +
      coord_equal() +
      ggthemes::theme_map() +
      theme(legend.position = "bottom")
    

    enter image description here