rrasterspatialr-raster

Cropping a map in the shape of a country boundary


I'm trying to download temperature data and visualise it using R. I used the raster package to download the temperature and ggplot2 to visualise it.

library(raster)
library(ggplot2)
library(magrittr)

tmax_data <- getData(name = "worldclim", var = "tmax", res = 10)
gain(tmax_data)=0.1
tmax_mean <- mean(tmax_data)
tmax_mean_df <- as.data.frame(tmax_mean, xy = TRUE, na.rm = TRUE)

tmax_mean_df %>%
  ggplot(aes(x=x,y=y)) +
  geom_raster(aes(fill = layer)) +
  labs(title = "Mean monthly maximum temperatures",
       subtitle = "For the years 1970-2000") +
  xlab("Longitude") +
  ylab("Latitude") +
  scale_fill_continuous(name = "Temperature (°C)")

However, the dataset contains the temperature values of the whole world. ut I want to visualise specific countries. I can crop the map by defining a bounding box but I'd like to crop the map in the shape of the country (instead of a square). Are there any packages that allow this functionality? Maybe by passing the shapefile of a country and cropping the map in that shape?


Solution

  • You can use the sf package in combination with raster::crop and raster::mask. Here is a demonstration for France:

    library(raster)
    library(ggplot2)
    library(magrittr)
    library(sf)
    
    tmax_data <- getData(name = "worldclim", var = "tmax", res = 10)
    gain(tmax_data)=0.1
    tmax_mean <- mean(tmax_data)
    
    france_sf <- st_as_sf(maps::map(database = "france", plot = FALSE, fill = TRUE))
    
    tmax_mean_france <- raster::crop(
      raster::mask(tmax_mean, as_Spatial(france_sf)),
      as_Spatial(france_sf)
    )
    
    tmax_mean_france_df <- as.data.frame(tmax_mean_france, xy = TRUE, na.rm = TRUE)
    
    tmax_mean_france_df %>%
      ggplot(aes(x=x,y=y)) +
      geom_raster(aes(fill = layer)) +
      labs(title = "Mean monthly maximum temperatures **in France**",
           subtitle = "For the years 1970-2000") +
      xlab("Longitude") +
      ylab("Latitude") +
      scale_fill_continuous(name = "Temperature (°C)")
    

    enter image description here