Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Plotting a ggplot world map with countries colored according to number ranges

Tags:

r

maps

ggplot2

I am trying to plot a map with ggplot for the first time and I am having problems achieving what I have in mind.

First of all, I have a data frame where every country code is associated to a number. For example:

id        count
US        2030
DE        1001
UA        730
SY        229

I would like to obtain a ggplot map where countries are colored by number range (for example: more than 2000 dark red, 1000-2000 red, 1000-600 orange, 600-200 yellow, less than 100 white). The color itself is not important, I just would like to have it becoming paler the lower the count is.

This is what I tried:

 world_map <- map_data(map = "world")
 world_map$region <- iso.alpha(world_map$region)
    
 ggplot(df, aes(map_id = id)) +
   geom_map(aes(fill = frequency), map = world_map) +
   expand_limits(x = world_map$long, y = world_map$lat) +
   scale_colour_manual(name = "counts", values = cols,
                    breaks = c(2000,1000,600,200), 
                    labels=c("more than 2000","2000-1000","1000-600","600-200")) +  
   theme_void() +
   coord_fixed()

When I try to execute this code I obtain the following error message

Don't know how to automatically pick scale for object of type function. Defaulting to continuous. Error: Aesthetics must be valid data columns. Problematic aesthetic(s): fill = frequency. Did you mistype the name of a data column or forget to add after_stat()?

Now I understand that there is a problem in how I set my parameters but I cannot find any solution to this in the internet (or maybe I am too much of a beginner to correctly understand it).

like image 973
Jess Avatar asked Nov 06 '25 11:11

Jess


1 Answers

My apologies for any confusion. I think this is what you're looking for.

First, would use cut to put your count column into groups, with your desired labels. This will create a factor count_group.

If you want to reorder the labels in the plot legend, you can reorder this factor with fct_rev from forcats.

Then, would use this for your fill in geom_map, and you can use scale_fill_manual to define your colors. In this case, you might want the Reds palette.

To add the borders around countries, use geom_polygon with NA for fill.

library(maps)
library(RColorBrewer)
library(forcats)

df <- data.frame(
  id = c("US", "DE", "UA", "SY"),
  count = c(2030, 1001, 730, 229)
)

df$count_group <- cut(df$count, 
                      breaks = c(-Inf, 200, 600, 1000, 2000, Inf), 
                      labels = c("Less than 200", "600-200", "1000-600", "2000-1000", "More than 2000"))

world_map <- map_data(map = "world")
world_map$region <- iso.alpha(world_map$region)

ggplot(df) +
  geom_map(aes(map_id = id, fill = fct_rev(count_group)), map = world_map) +
  geom_polygon(data = world_map, aes(x = long, y = lat, group = group), colour = 'black', fill = NA) +
  expand_limits(x = world_map$long, y = world_map$lat) +
  scale_fill_manual(name = "Counts", values = rev(brewer.pal(5, name = "Reds"))) +
  theme_void() +
  coord_fixed()

Plot

map with black borders and filled by count

like image 147
Ben Avatar answered Nov 09 '25 07:11

Ben



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!