Search code examples
rkeymapsscalelegend

How to add continuous color legend to an R map made with maps


I'm using the R code shown below, which loads libraries maps and RColorBrewer, to create a map of the world with countries color-coded by population rank. As you can see in the image below, I'm using a green palette in which the darker the green, the larger the population.

I'd like to add a continuous color legend showing the full palette to denote that light green = small population and dark green = large population, but I can't find a way to do it via maps. Could you tell me what is the easiest way to add a continuous color legend (or color key/color scale) to my map?

# Load libraries
library(maps)
library(RColorBrewer)

# Load world data
data(world.cities)

# Calculate world population by country
world.pop = aggregate(x=world.cities$pop, by=list(world.cities$country.etc),
                      FUN=sum)
world.pop = setNames(world.pop, c('Country', 'Population'))

# Create a color palette
palette = colorRampPalette(brewer.pal(n=9, name='Greens'))(nrow(world.pop))

# Sort the colors in the same order as the countries' populations
palette = palette[rank(-world.pop$Population)]

# Draw a map of the world
map(database='world', fill=T, col=palette, bg='light blue')

enter image description here


Solution

  • Within the library SDMTools there is the function legend.gradient

    adding this code to the end of your code should give the desired result:

    # Draw a map of the world
    map(database='world', fill=T, col=palette, bg='light blue')
    x = c(-20, -15, -15, -20)
    y = c(0, 60, 60, 0)
    legend.gradient(cbind(x = x - 150, y = y - 30), 
                      cols = brewer.pal(n=9, name='Greens'), title = "TITLE", limits = "")
    

    You will need to fiddle with the x & y coordinates to get the legend into the desired location however.

    EDIT

    The x and y coordinates also adjust the shape of the box so I changed the code so that the box shape would not change if you only alter the numbers within the legend.gradient function. Below is what this code should produce

    enter image description here