Mark
Mark

Reputation: 1769

European Map using R

I would need to draw, in R the map of the European Union and a shaded circle that overlaps it. The circle should have a center at a point with known longitude and latitude and a predetermined radius.

First, I can't even draw the map, even though the code doesn't throw out any errors. The code is:

library(ggplot2)
library(grid)
library(rworldmap)

# 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",
                   "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                   "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                   "Portugal","Romania","Slovakia","Slovenia","Spain",
                   "Sweden")
# Select only the index of states member of the E.U.
indEU <- which(worldMap$NAME%in%europeanUnion)

# 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")
  return(df)
})

europeCoords <- do.call("rbind", europeCoords)

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)]

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))

How can I fix the problem and add the circle?

Thank you!

Upvotes: 0

Views: 5917

Answers (1)

mrhellmann
mrhellmann

Reputation: 5559

You might want to consider using the sf (simple features) package to work with geographic data.

Below is code to map the countries you've specified, and to plot a circle centered in Germany. You may need to crop or filter the data, as there are a few EU landmasses far outside what most consider 'Europe'.

The circle turns out a bit wonky due to the projection over a large area.

library(ggplot2)
library(grid)
#library(rworldmap)
library(sf)
#> Linking to GEOS 3.8.0, GDAL 3.0.4, PROJ 6.3.1
library(dplyr)
#> 
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#> 
#>     filter, lag
#> The following objects are masked from 'package:base':
#> 
#>     intersect, setdiff, setequal, union


# Member States of the European Union
europeanUnion <- c("Austria","Belgium","Bulgaria","Croatia","Cyprus",
                   "Czech Rep.","Denmark","Estonia","Finland","France",
                   "Germany","Greece","Hungary","Ireland","Italy","Latvia",
                   "Lithuania","Luxembourg","Malta","Netherlands","Poland",
                   "Portugal","Romania","Slovakia","Slovenia","Spain",
                   "Sweden")

library(rnaturalearth)
world_map <- ne_countries(scale = 50, returnclass = 'sf')
europe_map <- world_map %>% filter(name %in% europeanUnion)

circle <- st_as_sfc(st_bbox(europe_map %>% filter(name == 'Germany'))) %>%
  st_transform(3035)%>%  ## <- change projection to one in meters
  st_centroid() %>%      ## centroid point of the bounding box of germany
  st_buffer(dist = 1e6) ## <- 1 million meters


p <- ggplot() + 
  geom_sf(data = europe_map, fill = 'orange') + 
  geom_sf(data = circle, fill = 'black', alpha = .2) + 
  theme_void()

p

Created on 2020-10-27 by the reprex package (v0.3.0)

Edit addressing questions in comment:

# make a point for frankfurt:
frankfurt <- st_point(x = c(8.6821, 50.1109)) %>%  ## coords from google
  st_geometry()

# 1896km buffer (circle) around frankfurt
frankfurt_circle_1896 <- frankfurt %>%
  st_set_crs(4326) %>%
  st_transform(3035) %>%
  st_buffer(dist = 1896000) ## 1896km in m

## Crop the europe map, removing French Guana, etc.
## change x&y coords as needed, these are approximations
europe_bbox <- st_bbox(c(xmin = -12, xmax = 34, ymax = 71, ymin = 34), crs = st_crs(4326))

europe_map_cropped <- europe_map %>% 
  st_crop(europe_bbox)

# plotting
p2 <- ggplot() +
  geom_sf(data = europe_map_cropped, fill = 'orange') + 
  geom_sf(data = frankfurt_circle_1896, alpha = .2, fill = 'black') 

p2

enter image description here

Upvotes: 3

Related Questions