Skip to article frontmatterSkip to article content

Calculating climate normals of temperature and precipitation

This notebook shows how to calculate monthly climate normals for temperature and precipitation for districts in Sierra Leone based on data from ERA5-Land. Climate normals (see definition) are used as a baseline to evaluate year-to-year variability for weather and climate.

We will use earthkit, xarray and pandas (both included in earthkit) to perform the analysis.

import earthkit.data
from earthkit.transforms import aggregate

Loading climate data

Use earthkit.data to load a NetCDF file containing monthly temperature and precipitation values since 1990:

file = "../data/era5-land-monthly-temp-precip-1990-2025-sierra-leone.nc"
data = earthkit.data.from_source("file", file)

This file was downloaded from the “ERA5-Land monthly averaged data from 1950 to present” dataset. See this tutorial for how to download data from the Climate Data Store.

We convert the data returned to an xarray dataset and display the contents:

dataset = data.to_xarray()
dataset
Loading...

The dataset is covering Sierra Leone, and contains two data variables:

  • t2m: Temperature 2m above surface
  • tp: Total precipitation

The spatial resoulution for this gridded dataset is approximately 9x9 km, and the temporal resolution is monthly values.

We can drop the variables that we don’t need in our analysis. We will keep time (valid_time) and space (latitude and longitude) dimensions.

dataset_clean = dataset.drop_vars(['number', 'expver'])

Calculate climate normals

To calculate climate normals we need to select the 30 years reference period (1991-2020).

dataset_period = dataset_clean.sel(valid_time=slice('1991-01-01', '2020-12-01'))

This will give us 30 years of montly data. We can check that the valid_time dimension has 360 items (30 years x 12 months).

dataset_period.dims
FrozenMappingWarningOnValuesAccess({'valid_time': 360, 'latitude': 33, 'longitude': 33})

To calculate monthly climate normals for temperature we select the variable and subtract 273.15 to convert from kelvin to celcius.

temp = dataset_period['t2m'] - 273.15

Next we calculate the mean value for each month of the year.

temp_month = temp.groupby('valid_time.month').mean()

We can do the same with precipitation. The precipitation values are in meters and is given as the daily average for that month. We multiply each value by 1000 to get millimeters, and the numer of days to get the total precipitation for each month.

precip = dataset_period['tp'] * 1000 * dataset_period.valid_time.dt.days_in_month

We can now calculate the mean precipitation for each month of the year.

precip_month = precip.groupby('valid_time.month').mean()

Climate normals for districts

The last step is to calculate the climate normals for each district in Sierra Leone. First we need to load the districts from a GeoJSON file downloaded from DHIS2 Maps.

district_file = "../data/sierra-leone-districts.geojson"
features = earthkit.data.from_source("file", district_file)

To aggregate the temperature data to the org unit features we use the aggregate package of earthkit-transforms. See this notebook for more information.

temp_agg = aggregate.spatial.reduce(temp_month, features, mask_dim="id")

We can convert the result to a dataframe to display the normal temperature in degrees celcius for each month (1-12).

temp_df = temp_agg.to_dataframe()
temp_df.loc['O6uvpzGd5pu'] # Bo district
Loading...

We can do the same to calculate the normal monthly precipitation (mm) for each district:

precip_agg = aggregate.spatial.reduce(precip_month, features, mask_dim="id")
precip_df = precip_agg.to_dataframe()
precip_df.loc['O6uvpzGd5pu'] # Bo district
Loading...

If you have access to the DHIS2 Climate app you can check if the climate normals calculated are similar to the values calculated using Google Earth Engine.

See more examples from Copernicus Climate Change Service (C3S) of how to calculate climate normals.