Search code examples
rggplot2gisusmap

How to specify bin colors for plot_usmap?


I'm looking to create a heat map with a little more control over the color scale, specifically I want to have bins for ranges of values that will correspond to a specific color.

Below I provide some sample code to generate some data and make a plot. The issue seems to be how it maps the colors to the breaks, it is not a 1:1 correspondence, when I add more percentiles to the breaks it seems to stretch the colors.

It does not appear to be a large issue here, but when I apply this to the entire US data set I'm working with the color scheme really breaks down.

library(usmap)
library(ggplot2)

fips <- seq(45001,45091,2)
value <- rnorm(length(fips),3000,10000)
data <- data.frame(fips,value)
data$value[data$value<0]=0

plot_usmap(regions='counties',data=data,values="value",include="SC") +
  scale_fill_stepsn(breaks=c(as.numeric(quantile(data$value,seq(.25,1,.25)))),
                  colors=c("blue","green","yellow","red"))

plot_usmap(regions='counties',data=data,values="value",include="SC") +
  scale_fill_stepsn(breaks=c(as.numeric(quantile(data$value,seq(0,1,.1)))),
                    colors=c("blue","green","yellow","red"))

enter image description here

enter image description here

#data not provided for this bit
plot_usmap(regions='counties',data=datar,values="1969",exclude=c("AK","HI")) +
  scale_fill_stepsn(breaks=c(as.numeric(quantile(datar$`1969`,seq(0,1,.1)))),
                    colours=c("blue","green","yellow","red"))

enter image description here


Solution

  • One way would be to manually bin the percentiles and then use the factor levels for your manual breaks and labels.

    I've never used this high level function from usmap, so I don't know how to deal with this warning which comes up. Would personally prefer and recommend to use ggplot + geom_polygon or friends for more control.

    library(usmap)
    library(ggplot2)
    
    fips <- seq(45001,45091,2)
    value <- rnorm(length(fips),3000,10000)
    mydat <- base::data.frame(fips,value)
    mydat$value[mydat$value<0]=0
    
    mydat$perc_cuts <- as.integer(cut(ecdf(mydat$value)(mydat$value), seq(0,1,.25)))
    
    
    plot_usmap(regions='counties',
               data=mydat,
               values="perc_cuts",include="SC") +
      scale_fill_stepsn(breaks= 1:4, limits = c(0,4), labels = seq(.25, 1, .25),
                        colors=c("blue","green","yellow","red"),
                        guide = guide_colorsteps(even.steps = FALSE))
    #> Warning: Use of `map_df$x` is discouraged. Use `x` instead.
    #> Warning: Use of `map_df$y` is discouraged. Use `y` instead.
    #> Warning: Use of `map_df$group` is discouraged. Use `group` instead.
    

    Created on 2020-06-27 by the reprex package (v0.3.0)