Expected Climate Changes in Erlangen at +4 °C Global Warming

Author

Antonios Isidoros Avrithis

Aim of this tutorial

This tutorial examines how annual mean temperature and annual precipitation are expected to change in Erlangen, Germany, when global warming reaches +4 °C above the pre-industrial baseline (1850–1900) under the CMIP6 SSP5-8.5 scenario.

The tutorial will:

  1. locate Germany and Erlangen on a world map;
  2. read annual temperature- and precipitation-change rasters from the IPCC Interactive Atlas;
  3. crop and mask the rasters to Germany;
  4. use the Robinson projection on all maps;
  5. plot temperature and precipitation change with different colour palettes; and
  6. extract the raster values for Erlangen.

1. Packages

library(viridis) # colour palettes
Warning: package 'viridis' was built under R version 4.5.3
Loading required package: viridisLite
Warning: package 'viridisLite' was built under R version 4.5.2
library(terra) # raster data
Warning: package 'terra' was built under R version 4.5.3
terra 1.9.11
library(sf) # vector data
Warning: package 'sf' was built under R version 4.5.3
Linking to GEOS 3.14.1, GDAL 3.12.1, PROJ 9.7.1; sf_use_s2() is TRUE
library(rgplates) # map edge
Warning: package 'rgplates' was built under R version 4.5.3

2. Read the vector data

The data for the map plotting were already provided and downloaded to the working directory.Spatial analyses often combine vector and raster data. Here, Natural Earth provides the outlines of the world’s land areas, and the World Administrative Boundaries dataset provides country polygons. Germany will later be selected from the global dataset so that later analyses can focus only on the study area.

# Natural Earth
ne <- sf::st_read(
  "ne_10m_land.shx",
  quiet=TRUE
)

# countries
countries <- sf::st_read(
  "world-administrative-boundaries.shx",
  quiet=TRUE
)

# Germany - using a logical expression
germany <- countries[which(countries$name=="Germany"), ]

germany
Simple feature collection with 1 feature and 8 fields
Geometry type: MULTIPOLYGON
Dimension:     XY
Bounding box:  xmin: 5.865 ymin: 47.27472 xmax: 15.03382 ymax: 55.05653
Geodetic CRS:  WGS 84
         status color_code         region iso3 continent    name iso_3166_1_
42 Member State        DEU Western Europe  DEU    Europe Germany          DE
   french_shor                       geometry
42   Allemagne MULTIPOLYGON (((14.22555 53...

3. Create the Erlangen location

Using the coordinates of Erlangen to plot it aferwards in the map

erlangen <- matrix(
  c(10.97, 49.58),
  ncol=2
)

colnames(erlangen) <- c("lng", "lat")

erlangen
       lng   lat
[1,] 10.97 49.58
erlangenSF <- sf::st_as_sf(
  data.frame(
    name="Erlangen",
    lng=10.97,
    lat=49.58
  ),
  coords=c("lng", "lat")
)

sf::st_crs(erlangenSF) <- "WGS84"

erlangenSF
Simple feature collection with 1 feature and 1 field
Geometry type: POINT
Dimension:     XY
Bounding box:  xmin: 10.97 ymin: 49.58 xmax: 10.97 ymax: 49.58
Geodetic CRS:  WGS 84
      name            geometry
1 Erlangen POINT (10.97 49.58)

4. Robinson projection

The world map projection type we use here is Robinson, but many other types can also be used (e.g. Mollweide)

robinProj <- "ESRI:54030"

neRob <- sf::st_transform(
  ne,
  crs=robinProj
)

germanyRob <- sf::st_transform(
  germany,
  crs=robinProj
)

erlangenRob <- sf::st_transform(
  erlangenSF,
  crs=robinProj
)

# map edge
edge <- rgplates::mapedge()

edgeRob <- sf::st_transform(
  edge,
  crs=robinProj
)

5. Location of Germany and Erlangen

A first, wide view plot of the whole global map with erlangen and Germany marked

plot(
  edgeRob,
  col="#9bbff4",
  border=NA,
  reset=FALSE,
  main="Location of Germany and Erlangen"
)

plot(
  neRob$geometry,
  col="white",
  border="gray",
  add=TRUE
)

plot(
  germanyRob$geometry,
  col="orange",
  border="black",
  add=TRUE
)

plot(
  erlangenRob$geometry,
  pch=3,
  col="red",
  cex=2,
  add=TRUE
)

Location of Germany and Erlangen in Robinson projection.

6. Read the IPCC Atlas raster data

The selected climate setting should be CMIP6, SSP5-8.5, +4 °C global warming, the 1850–1900 baseline, and Annual season. Under these prefenreces, the data for mean temperature and average precipitation where obtained by the IPCC Atlas webpage. For this work we use the .shx format of the files.

temperature <- terra::rast(
  "MAT_map.nc"
)

precipitation <- terra::rast(
  "PREC_map.nc"
)

temperature
class       : SpatRaster 
size        : 180, 360, 1  (nrow, ncol, nlyr)
resolution  : 1, 1  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326) 
source      : MAT_map.nc 
varname     : tas_anom (GDAL Band Number 1) 
name        : tas_anom 
precipitation
class       : SpatRaster 
size        : 180, 360, 1  (nrow, ncol, nlyr)
resolution  : 1, 1  (x, y)
extent      : -180, 180, -90, 90  (xmin, xmax, ymin, ymax)
coord. ref. : lon/lat WGS 84 (EPSG:4326) 
source      : PREC_map.nc 
varname     : pr_relanom (GDAL Band Number 1) 
name        : pr_relanom 
names(temperature)
[1] "tas_anom"
names(precipitation)
[1] "pr_relanom"
cat(terra::crs(temperature))
BOUNDCRS[
    SOURCECRS[
        GEOGCRS["WGS 84",
            DATUM["World Geodetic System 1984",
                ELLIPSOID["WGS 84",6378137,298.257223563,
                    LENGTHUNIT["metre",1]]],
            PRIMEM["Greenwich",0,
                ANGLEUNIT["degree",0.0174532925199433]],
            CS[ellipsoidal,2],
                AXIS["geodetic latitude (Lat)",north,
                    ORDER[1],
                    ANGLEUNIT["degree",0.0174532925199433]],
                AXIS["geodetic longitude (Lon)",east,
                    ORDER[2],
                    ANGLEUNIT["degree",0.0174532925199433]],
            ID["EPSG",4326]]],
    TARGETCRS[
        GEOGCRS["WGS 84",
            DATUM["World Geodetic System 1984",
                ELLIPSOID["WGS 84",6378137,298.257223563,
                    LENGTHUNIT["metre",1]]],
            PRIMEM["Greenwich",0,
                ANGLEUNIT["degree",0.0174532925199433]],
            CS[ellipsoidal,2],
                AXIS["geodetic latitude (Lat)",north,
                    ORDER[1],
                    ANGLEUNIT["degree",0.0174532925199433]],
                AXIS["geodetic longitude (Lon)",east,
                    ORDER[2],
                    ANGLEUNIT["degree",0.0174532925199433]],
            ID["EPSG",4326]]],
    ABRIDGEDTRANSFORMATION["Transformation from WGS 84 to WGS84",
        METHOD["Position Vector transformation (geog2D domain)",
            ID["EPSG",9606]],
        PARAMETER["X-axis translation",0,
            ID["EPSG",8605]],
        PARAMETER["Y-axis translation",0,
            ID["EPSG",8606]],
        PARAMETER["Z-axis translation",0,
            ID["EPSG",8607]],
        PARAMETER["X-axis rotation",0,
            ID["EPSG",8608]],
        PARAMETER["Y-axis rotation",0,
            ID["EPSG",8609]],
        PARAMETER["Z-axis rotation",0,
            ID["EPSG",8610]],
        PARAMETER["Scale difference",1,
            ID["EPSG",8611]]]]
cat(terra::crs(precipitation))
BOUNDCRS[
    SOURCECRS[
        GEOGCRS["WGS 84",
            DATUM["World Geodetic System 1984",
                ELLIPSOID["WGS 84",6378137,298.257223563,
                    LENGTHUNIT["metre",1]]],
            PRIMEM["Greenwich",0,
                ANGLEUNIT["degree",0.0174532925199433]],
            CS[ellipsoidal,2],
                AXIS["geodetic latitude (Lat)",north,
                    ORDER[1],
                    ANGLEUNIT["degree",0.0174532925199433]],
                AXIS["geodetic longitude (Lon)",east,
                    ORDER[2],
                    ANGLEUNIT["degree",0.0174532925199433]],
            ID["EPSG",4326]]],
    TARGETCRS[
        GEOGCRS["WGS 84",
            DATUM["World Geodetic System 1984",
                ELLIPSOID["WGS 84",6378137,298.257223563,
                    LENGTHUNIT["metre",1]]],
            PRIMEM["Greenwich",0,
                ANGLEUNIT["degree",0.0174532925199433]],
            CS[ellipsoidal,2],
                AXIS["geodetic latitude (Lat)",north,
                    ORDER[1],
                    ANGLEUNIT["degree",0.0174532925199433]],
                AXIS["geodetic longitude (Lon)",east,
                    ORDER[2],
                    ANGLEUNIT["degree",0.0174532925199433]],
            ID["EPSG",4326]]],
    ABRIDGEDTRANSFORMATION["Transformation from WGS 84 to WGS84",
        METHOD["Position Vector transformation (geog2D domain)",
            ID["EPSG",9606]],
        PARAMETER["X-axis translation",0,
            ID["EPSG",8605]],
        PARAMETER["Y-axis translation",0,
            ID["EPSG",8606]],
        PARAMETER["Z-axis translation",0,
            ID["EPSG",8607]],
        PARAMETER["X-axis rotation",0,
            ID["EPSG",8608]],
        PARAMETER["Y-axis rotation",0,
            ID["EPSG",8609]],
        PARAMETER["Z-axis rotation",0,
            ID["EPSG",8610]],
        PARAMETER["Scale difference",1,
            ID["EPSG",8611]]]]
terra::ext(temperature)
SpatExtent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)
terra::ext(precipitation)
SpatExtent : -180, 180, -90, 90 (xmin, xmax, ymin, ymax)

7. Select the required layers

temperature <- temperature[[1]]
precipitation <- precipitation[[1]]

After rendering, check the output of names(temperature) and names(precipitation) above. If either file contains several layers, replace [[1]] with the correct layer name.

8. Crop and mask the rasters to Germany

Now, the rasters of temperature and precipitation that project on the area of Germany are cropped from the global reconstruction and masked on the map of the country

temperatureGermany <- terra::crop(
  temperature,
  germany
)

temperatureGermany <- terra::mask(
  temperatureGermany,
  germany
)
Warning: [mask] CRS do not match
precipitationGermany <- terra::crop(
  precipitation,
  germany
)

precipitationGermany <- terra::mask(
  precipitationGermany,
  germany
)
Warning: [mask] CRS do not match

9. Extract the values for Erlangen

With extract function, the values for Erlangen climatological change are obtained by identifying the raster cell containing the coordinates of Erlangen.

# Extract Erlangen values

temperatureErlangen <- terra::extract(
  temperature,
  erlangen
)

precipitationErlangen <- terra::extract(
  precipitation,
  erlangen
)

temperatureErlangen
  tas_anom
1 5.038018
precipitationErlangen
  pr_relanom
1   2.028173
# Store the numerical values
temperatureValue <- as.numeric(temperatureErlangen[[1]][1])
precipitationValue <- as.numeric(precipitationErlangen[[1]][1])

10. Project the rasters

temperatureRob <- terra::project(
  temperatureGermany,
  robinProj,
  method="bilinear"
)

precipitationRob <- terra::project(
  precipitationGermany,
  robinProj,
  method="bilinear"
)

11. Annual temperature change

Different colour palettes improve map readability, and we ensure to use a color-blind friendly pallete. The ‘inferno’ palette is used for temperature because its gradual transition from dark to bright colours is well correlated conceptually with the warming increase trend.

plot(
  temperatureRob,
  col=inferno(100),
  axes=FALSE,
  main="Annual temperature change at +4 degrees C"
)

plot(
  germanyRob$geometry,
  col=NA,
  border="black",
  add=TRUE
)

plot(
  erlangenRob$geometry,
  pch=3,
  col="red",
  cex=2,
  add=TRUE
)

Expected annual temperature change in Germany at +4 °C global warming.

12. Annual precipitation change

For the annual precipitation change a different pallete with the same criteria should be used.

plot(
  precipitationRob,
  col=viridis(100),
  axes=FALSE,
  main="Annual precipitation change at +4 degrees C"
)

plot(
  germanyRob$geometry,
  col=NA,
  border="black",
  add=TRUE
)

plot(
  erlangenRob$geometry,
  pch=3,
  col="red",
  cex=2,
  add=TRUE
)

Expected annual precipitation change in Germany at +4 °C global warming.

13. Results for Erlangen

The expected annual temperature change for the raster cell containing Erlangen is 5.04 °C relative to the 1850–1900 baseline.

The expected annual precipitation change for the raster cell containing Erlangen is 2.03% relative to the 1850–1900 baseline.

cat(
  "Temperature change in Erlangen:",
  temperatureValue,
  "degrees C\n"
)
Temperature change in Erlangen: 5.038018 degrees C
cat(
  "Precipitation change in Erlangen:",
  precipitationValue,
  "percent\n"
)
Precipitation change in Erlangen: 2.028173 percent

These values represent the climate-model raster cell containing Erlangen.

14. Interpretation

The +4 °C warming level refers to global mean warming. The local annual temperature change over Germany and Erlangen does not have to be exactly ranges from 4.2 to +5.2 °C but Erlangen shows about +5 °C MAT change. This is reasonable taking into account that in other global warming phases (PETM) higher latitudes showed greater warming than lower latitudes.

On the other hand, precipitation shows only value shifts, indicating an increase in annual precipitation relative to 1850–1900. However, it should be noted that there is no clue about intensified or weakened seasonality of precipitation or temperature in this investigation.

15. Conclusion

This tutorial demonstrated how raster and vector data can be combined to investigate expected climate changes in Erlangen. The analysis imported the spatial datasets, selected Germany, created the Erlangen point, cropped and masked the climate rasters, extracted the local values, projected all maps to Robinson, and plotted annual temperature and precipitation change.

Data sources

The climate data were obtained from the IPCC Working Group I Interactive Atlas and represent CMIP6 SSP5-8.5 conditions at +4 °C global warming relative to 1850–1900.

Natural Earth supplied the world land polygons. World Administrative Boundaries supplied the country polygons.

Reproducibility information

sessionInfo()
R version 4.5.1 (2025-06-13 ucrt)
Platform: x86_64-w64-mingw32/x64
Running under: Windows 11 x64 (build 26200)

Matrix products: default
  LAPACK version 3.12.1

locale:
[1] LC_COLLATE=English_United Kingdom.utf8 
[2] LC_CTYPE=English_United Kingdom.utf8   
[3] LC_MONETARY=English_United Kingdom.utf8
[4] LC_NUMERIC=C                           
[5] LC_TIME=English_United Kingdom.utf8    

time zone: Europe/Berlin
tzcode source: internal

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] rgplates_0.6.1    sf_1.1-1          terra_1.9-11      viridis_0.6.5    
[5] viridisLite_0.4.2

loaded via a namespace (and not attached):
 [1] gtable_0.3.6       jsonlite_2.0.0     dplyr_1.2.1        compiler_4.5.1    
 [5] tidyselect_1.2.1   Rcpp_1.1.0         gridExtra_2.3      scales_1.4.0      
 [9] yaml_2.3.12        fastmap_1.2.0      ggplot2_4.0.3      R6_2.6.1          
[13] generics_0.1.4     classInt_0.4-11    knitr_1.51         htmlwidgets_1.6.4 
[17] tibble_3.3.0       units_1.0-0        DBI_1.2.3          pillar_1.11.1     
[21] RColorBrewer_1.1-3 rlang_1.2.0        xfun_0.57          S7_0.2.1          
[25] cli_3.6.5          magrittr_2.0.4     class_7.3-23       digest_0.6.38     
[29] grid_4.5.1         rstudioapi_0.18.0  lifecycle_1.0.5    vctrs_0.7.3       
[33] KernSmooth_2.23-26 proxy_0.4-27       evaluate_1.0.5     glue_1.8.0        
[37] farver_2.1.2       codetools_0.2-20   e1071_1.7-16       rmarkdown_2.31    
[41] tools_4.5.1        pkgconfig_2.0.3    htmltools_0.5.9   

References

This tutorial used climatic data from published datasets of IPCC Atlas (Intergovernmental Panel on Climate Change 2021).

References

Intergovernmental Panel on Climate Change. 2021. IPCC Working Group i Interactive Atlas. Https://interactive-atlas.ipcc.ch/.