In this post, I will present a way to plot a European Union map using R. We ran across this question with @gVermandel.

EDIT (2013-02-18) : As mentioned in the comment section below, there is a nice package I wasn’t aware of, that does (with more ease and offering a more beautiful result) the same thing:

New version of this post (May 2022)

Let us download a world map from Natural Earth. To that end, we can use two packages: {rnaturalearth} and {rnaturalearthdata}.


The world map can be obtained as follows:

world_map <- ne_countries(scale = 50, returnclass = 'sf')

We will focus only on the members of the European Union here:

# Member States of the European Union
european_union <- c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                    "Czech Rep.","Denmark","Estonia","Finland","France",
                    "Sweden","United Kingdom")

Let us filter the elements in the world map data frame to keep only the countries we are interested in:

european_union_map <- 
  world_map %>% 
  filter(name %in% european_union)

If we wan to focus only on the European continent, we can crop the data by defining a bounding box:

bbox_europe <- st_bbox(c(xmin = -10, ymin = 20, xmax = 50, ymax = 80), crs = st_crs(european_union_map))
european_union_map_cropped <- st_crop(european_union_map, bbox_europe)

Let us create some dummy data in a tibble. A first column indicates the names of the countries and the second one is for a variable of interest.

df <- 
  tibble(country = european_union,
       some_value = runif(length(european_union)))

All we need to do is to add these information in the map data frame:

map <- 
  european_union_map_cropped %>% 
  left_join(df, by = c("name" = "country"))

And voilà! The map can then easily plotted thanks to the {sf} package:

ggplot(data = map) +
  geom_sf(mapping = aes(fill = some_value)) +
  scale_fill_gradient(name = "Growth Rate", low = "#FF0000FF", high = "#FFFF00FF", na.value = "grey50") +
  labs(title = "(Fictitious) growth rate.") +
  theme(plot.title.position = "plot")
European Map

(Fictious data)

Old version of this post

As you know, some countries are missing in the maps package. So, instead of working with that package, we will use the rworldmap one, available on CRAN. We will also need two more packages : ggplot2 and grid.


First, let’s get the coordinates of every countries from the getMap function. We need the names of the 28 member states of the E.U..

# Get the world map
worldMap <- getMap()

# Member States of the European Union
europeanUnion <- c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                   "Czech Rep.","Denmark","Estonia","Finland","France",
                   "Sweden","United Kingdom")
# Select only the index of states member of the E.U.
indEU <- which(worldMap$NAME%in%europeanUnion)

Then we can get the coordinates for each country.

# Extract longitude and latitude border's coordinates of members states of E.U. 
europeCoords <- lapply(indEU, function(i){
  df <- data.frame(worldMap@polygons[[i]]@Polygons[[1]]@coords)
  df$region =as.character(worldMap$NAME[i])
  colnames(df) <- list("long", "lat", "region")

europeCoords <-"rbind", europeCoords)

For the purpose of this example, we’ll assign some random values to each country.

# Add some data for each member
value <- sample(x = seq(0,3,by = 0.1), size = length(europeanUnion),
                replace = TRUE)
europeanUnionTable <- data.frame(country = europeanUnion, value = value)
europeCoords$value <- europeanUnionTable$value[match(europeCoords$region,europeanUnionTable$country)]

Finally, we can plot the map.

# Plot the map
P <- ggplot() + geom_polygon(data = europeCoords, aes(x = long, y = lat, group = region, fill = value),
                             colour = "black", size = 0.1) +
  coord_map(xlim = c(-13, 35),  ylim = c(32, 71))

P <- P + scale_fill_gradient(name = "Growth Rate", low = "#FF0000FF", high = "#FFFF00FF", na.value = "grey50")

P <- P + theme(#panel.grid.minor = element_line(colour = NA), panel.grid.minor = element_line(colour = NA),
               #panel.background = element_rect(fill = NA, colour = NA),
               axis.text.x = element_blank(),
               axis.text.y = element_blank(), axis.ticks.x = element_blank(),
               axis.ticks.y = element_blank(), axis.title = element_blank(),
               #rect = element_blank(),
               plot.margin = unit(0 * c(-1.5, -1.5, -1.5, -1.5), "lines"))
Warning: fake data.

Member Countries of the European Union (Warning: fake data)

The legend title is a bit too close to the legend keys to my opinion… As suggested by Ronald Burggraaf (thank you!), a way to add some space between these elements is by adding a breakline character to the title :

P <- P + scale_fill_gradient(name = "Growth Raten", low = "#FF0000FF", high = "#FFFF00FF", na.value = "grey50")

10 thoughts on “European Map using R

  1. Great stuff, thanks.

    Are you aware of any R package that includes historic European boundaries, hopefully going back to the medieval period?

  2. Hi, thank you so much for this!

    have a question. Do you know by any chance how to add migration flows on this map. lets say I have data how many people went to each country is it a way to code that into the map. like to make circles where there are the most migrants?

    Thank you

  3. Hello
    I have a Error when I try. It doesn’t work

    “Error in loadNamespace(name) : there is no package called ‘mapproj’”

    1. Hi, you need to install a missing package: `mapproj` (and also, if I recall correctly, some missing libraries outside R).

Leave a Reply to Naim Bro Cancel reply

Your email address will not be published.

Time limit is exhausted. Please reload CAPTCHA.