Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Downloading Climate Data from Optimized ERA5-Land Zarr Archives

In this notebook we will demonstrate how we can use Climate Tools and dhis2eo to efficiently retrieve climate data from optimized Zarr archives of the ERA5-Land dataset, hosted at the DestinE Earth Data Hub.

It should be noted that this is an alternative to the examples showing how to get ERA5-Land data from the Climate Data Store. The benefit of getting ERA5-Land data from DestinE is that it fetches the data from cloud-optimized Zarr archives, which is much faster than getting the same data from the Climate Data Store.

Important: Make sure you have followed these instructions to authenticate and allow access the Earth Data Hub zarr files.


What you need

We start by importing the necessary libraries:

import geopandas as gpd
import xarray as xr

from dhis2eo.data.destine import era5_land

In order to know which geographical area we should download data for, we also load our Sierra Leone organisation unit GeoJSON file downloaded from DHIS2. Alternative, see our guide for how to fetch organisation units directly from your DHIS2 instance.

org_units = gpd.read_file('../../data/sierra-leone-districts.geojson')
org_units
Loading...

Downloading ERA5-Land data

The dhis2eo.data.destine.era5_land module allows you to easily access and download climate data from DestinE’s optimized zarr-archive of the ERA5-Land dataset.

Hourly data

To import daily ERA5-Land data into DHIS2, we recommend using era5_land.hourly to download the hourly version of the data, and then aggregating up to the daily level. This allows you to define the correct days for your local timezone when aggregating from hourly to daily values.

Parameters

We set the start and end parameters to only get climate data for the months of July, August, and September of 2025, and set the bounding box (bbox) to only get data for the spatial extent of the org units.

We also specify a dirname for where the data should be saved and a prefix for naming the downloaded files.

Finally, we specify which climate variables we want to download - specifically 2m temperature and total precipitation. For a list of all the available ERA5-Land variables, see the Earth Data Hub’s ERA5-Land Dataset Page.

start = "2025-07"
end = "2025-09"
bbox = org_units.total_bounds
dirname = '../../data/local'
prefix = 'era5land_hourly_sierra_leone'
variables = ["t2m", "tp"]

Download to disk

Run the download function which will retrieve the data one month at a time to the location you specified. Downloads can take a few minutes for each month downloaded. The returned list shows the location of the downloaded files:

files = era5_land.hourly.download(start=start, end=end, bbox=bbox, dirname=dirname, prefix=prefix, variables=variables)
files
INFO - 2026-04-27 11:59:12,890 - dhis2eo.data.destine.era5_land.hourly - Month 2025-7
INFO - 2026-04-27 11:59:12,893 - dhis2eo.data.destine.era5_land.hourly - Opening zarr archive from https://data.earthdatahub.destine.eu/era5/reanalysis-era5-land-no-antartica-v0.zarr
INFO - 2026-04-27 11:59:22,693 - dhis2eo.data.destine.era5_land.hourly - Correcting longitude coords to range -180 to 180
INFO - 2026-04-27 11:59:30,292 - dhis2eo.data.destine.era5_land.hourly - Computing bbox to use for subsetting
INFO - 2026-04-27 11:59:30,298 - dhis2eo.data.destine.era5_land.hourly - Subsetting zarr archive to bbox with padding: -13.403500000000022 6.817599999999999 -10.165799999999978 10.100400000000002
INFO - 2026-04-27 11:59:30,302 - dhis2eo.data.destine.era5_land.hourly - Subsetting zarr archive to date range: 2025-07-01 to 2025-07-31
INFO - 2026-04-27 11:59:30,325 - dhis2eo.data.destine.era5_land.hourly - Saving data from DestinE Earth Data Hub...
INFO - 2026-04-27 11:59:30,325 - dhis2eo.data.destine.era5_land.hourly - --> FrozenMappingWarningOnValuesAccess({'valid_time': 744, 'latitude': 33, 'longitude': 33})
INFO - 2026-04-27 11:59:43,877 - dhis2eo.data.destine.era5_land.hourly - Month 2025-8
INFO - 2026-04-27 11:59:43,879 - dhis2eo.data.destine.era5_land.hourly - Subsetting zarr archive to date range: 2025-08-01 to 2025-08-31
INFO - 2026-04-27 11:59:43,882 - dhis2eo.data.destine.era5_land.hourly - Saving data from DestinE Earth Data Hub...
INFO - 2026-04-27 11:59:43,883 - dhis2eo.data.destine.era5_land.hourly - --> FrozenMappingWarningOnValuesAccess({'valid_time': 744, 'latitude': 33, 'longitude': 33})
INFO - 2026-04-27 11:59:49,399 - dhis2eo.data.destine.era5_land.hourly - Month 2025-9
INFO - 2026-04-27 11:59:49,400 - dhis2eo.data.destine.era5_land.hourly - Subsetting zarr archive to date range: 2025-09-01 to 2025-09-30
INFO - 2026-04-27 11:59:49,403 - dhis2eo.data.destine.era5_land.hourly - Saving data from DestinE Earth Data Hub...
INFO - 2026-04-27 11:59:49,404 - dhis2eo.data.destine.era5_land.hourly - --> FrozenMappingWarningOnValuesAccess({'valid_time': 720, 'latitude': 33, 'longitude': 33})
[WindowsPath('C:/Users/karimba/Documents/Github/climate-tools/docs/guides/data/local/era5land_hourly_sierra_leone_2025-07.nc'), WindowsPath('C:/Users/karimba/Documents/Github/climate-tools/docs/guides/data/local/era5land_hourly_sierra_leone_2025-08.nc'), WindowsPath('C:/Users/karimba/Documents/Github/climate-tools/docs/guides/data/local/era5land_hourly_sierra_leone_2025-09.nc')]

The download function treats the files saved under the given dirname and prefix as a cache, so it can safely be rerun multiple times without re-downloading. To ignore the cache and fetch fresh data you can set overwrite=True.

Inspect the data

Now that the files exists on disk, there are many ways we could work with them. For now, let’s open the files as a single xarray dataset, by passing them to xr.open_mfdataset():

ds = xr.open_mfdataset(files)

Inspecting the data we see that the xarray dataset contains the data variables t2m (2m temperature), and tp (total precipitation), and has 2208 hours in the time dimension (or 3 months of hourly data):

ds
Loading...

Finally, let’s check what the precipitation (tp) was at 12:00 on August 31:

ds.sel(valid_time='2025-08-31T12:00')['tp'].plot(cmap='YlGnBu')
<Figure size 640x480 with 2 Axes>

Important: Since DHIS2 does not deal directly with hourly data, you will also need to aggregate from hourly to daily data before you can import the data to DHIS2.

Next steps

This notebook has showed how to download both hourly and monthly ERA5-Land climate data. For guidance on what to do with the data after downloading, see:

If you want to skip to the end, you can also check out this example workflow that includes all the steps needed to download and import ERA5-Land data from start to finish.