rcolorsmapsplotlyviridis

How to use a non-default colorscale in R plotly chloropleth maps?


I'm creating a chloropleth map in R using plotly, and the only trouble I'm having is setting a different colorscale. I would like to use the magma colorscale from the viridis package, but I can't seem to figure out the correct way to do it. I've tried googling and searching, but no answers are quite working. Anyone have any advice?

The error I'm getting is: "unique() only applies to vectors." I've tried setting "discrete = TRUE" but that does not work.

Let me know if you need more information.

create_cw_map <- function(data, color_var) {
  if (is.null(data))
    return(NULL)

  g <- list(scope = "usa",
           projection = list(type = "albers usa"),
           showlakes = FALSE)

  cw_map <- plot_geo(data,
                     locationmode = "USA-states") %>%
            add_trace(z = ~ get(color_var),
                      locations = ~ state,
                      color = ~ get(color_var),
                      colorscale =  scale_fill_viridis(option = "magma")) %>%
            colorbar(title = color_var) %>%
            layout(geo = g)

            print(cw_map)
}

Solution

  • I do not have access to your data. So I decided to use the tutorial data from the plotly package to demonstrate how to use viridis colors.

    Continuous veariable

    If you read the help page for plot_ly(), you see that colors is specified as either a colorbrewer2.org palette name (e.g. "YlOrRd" or "Blues"), or a vector of colors to interpolate in hexadecimal "#RRGGBB" format, or a color interpolation function like colorRamp(). What you can do is to create a vector of colors using magma() in the viridisLite package. Here I specified colors = magma(50, alpha = 1, begin = 0, end = 1, direction = 1). n = 50 indicates that I want 50 colors in the color vector. You want to play around with this number for your own case.

    library(dplyr)
    library(viridis)
    library(plotly)
    
    df <- read.csv("https://raw.githubusercontent.com/plotly/datasets/master/2011_us_ag_exports.csv")
    df$hover <- with(df, paste(state, '<br>', "Beef", beef, "Dairy", dairy, "<br>",
                           "Fruits", total.fruits, "Veggies", total.veggies,
                           "<br>", "Wheat", wheat, "Corn", corn))
    
    # give state boundaries a white border
    l <- list(color = toRGB("white"), width = 2)
    
    # specify some map projection/options
    g <- list(scope = 'usa',
              projection = list(type = 'albers usa'),
              showlakes = TRUE,
              lakecolor = toRGB('white'))
    
    p <- plot_geo(df, locationmode = 'USA-states') %>%
           add_trace(z = ~total.exports,
                     text = ~hover,
                     locations = ~code,
                     color = ~total.exports,
                     colors = magma(50, alpha = 1, begin = 0, end = 1, direction = 1)) %>%
           colorbar(title = "Millions USD") %>%
           layout(title = '2011 US Agriculture Exports by State<br>(Hover for breakdown)',
                  geo = g)
    

    enter image description here

    Categorical variable

    After posting my answer, I thought you were using a categorical variable. I played around the example and think that it is tricky to create a chloropleth map with such a variable in plotly. At least, I can assign colors to polygons based on a categorical variable, but a color bar appears in a funny way. So I removed it. (If anybody can improve this part, please do so.)

    Using the same data, I did the following. I created a categorical variable using ntile() in the dplyr package. I randomly created 9 levels in total.exports. Then, I created nine colors using magma(). When I drew the map below, I used colors = foo[df$export_nth]. This is basically creating 50 colors using foo. export_nth is used as index numbers. I hope this will help you to think how you can solve your situation.

    mutate(df, export_nth = ntile(x = total.exports, n = 9)) -> df
    
    # Create a magma color vector
    
    foo <- magma(n = 9, alpha = 1, begin = 0, end = 1, direction = 1)
    
    p <- plot_geo(df, locationmode = 'USA-states') %>%
         add_trace(z = ~export_nth,
                   text = ~hover,
                   locations = ~code,
                   colors = foo[df$export_nth],
                   color = ~export_nth,
                   showscale = FALSE) %>%
         layout(title = '2011 US Agriculture Exports by State<br>(Hover for breakdown)',
                geo = g)
    

    enter image description here