Sal Sal - 1 month ago 19
R Question

Color coded world map with ggplot2 and geom_map

I am trying to plot a world map where the color of each country depends on the value of a variable in the dataframe.

> affiliation
# A tibble: 252 × 2
region value
<chr> <dbl>
1 Aruba 0
2 Afghanistan 0
3 Angola 0
4 Anguilla 0
5 Albania 0
6 Finland 1
7 Andorra 0
8 United Arab Emirates 0
9 Argentina 2
10 Armenia 0
# ... with 242 more rows


The code I have works fine:

library(ggplot2)
library(ggthemes)

ggplot(affiliation, aes(map_id = region)) +
geom_map(aes(fill = value), map = worldMap, color='grey', size=0.3) +
expand_limits(x = worldMap$long, y = worldMap$lat) +
theme_few()+
theme(legend.position = "bottom",
axis.ticks = element_blank(),
axis.title = element_blank(),
axis.text = element_blank()) +
scale_fill_gradient(low="white", high="darkblue", name="Number of Affiliates") +
guides(fill = guide_colorbar(barwidth = 10, barheight = .5))


My problem is that most of the values are 0, 1 or 2, very few values in the 20-30 but 1 outlier country has a value in the 330. This makes the color scale useless because that country is shown saturated in color whereas all the countries with much lower values appear white.

I tried to replace
geom_map(aes(fill = value),…
with
geom_map(aes(fill = log(value)),…
but in this case the scale in the legend shows 0 to 5+ (instead of 0 to 330).

What can I do to better control the color saturation of the many countries that have low values in order to make them more visible on the world map ?
Thank you

Answer

Most of the continuous scale functions in ggplot2 accept a trans argument, which specifies the transformation to use on that aesthetic. This will automatically handle the transformation and labelling.

In your example, adding trans = "log1p" (not just "log" because your data has a couple 0 values) to the arguments to scale_gradient_n could help.