Skip to Content
L’échange d’apprentissage de HIC débute le 13 Juillet 2026. Voir le programme

Cartes climatiques

Ce pipeline cartographie les indicateurs climatiques annuels sur les secteurs du Rwanda. Il nettoie les valeurs climatiques ERA5-Land indexées par établissement de santé, aligne leurs noms sur les limites admin3, joint les deux et produit une carte choroplèthe par classes. La source complète est analysis/spatial-analysis/Climate_maps.ipynb.

Le résultat final est une carte choroplèthe à deux panneaux de la température moyenne annuelle et des précipitations totales :

charts/climate_two_panel_map.png

Les données

Le classeur climatique (Climate data.xls) contient les variables ERA5-Land par établissement de santé, la localisation de l’établissement étant décrite par la hiérarchie des unités organisationnelles DHIS2. Seules cinq variables sont conservées :

Colonne sourceRenommée en
RF001 Relative humidity (ERA5-Land)humidity
TMP001 Air temperature (ERA5-Land)Average_temperature
TMP002 Max air temperature (ERA5-Land)Max_temperature
TMP005 Min temperature (ERA5-Land)Min_temperature
RF003 Precipitation (ERA5-Land)Rainfall

Les niveaux d’unités organisationnelles correspondent à la hiérarchie administrative — orgunitlevel3 est le district et orgunitlevel5 le secteur, qui sert de clé de jointure pour admin3.

Pipeline

Lire le classeur climatique

L’en-tête s’étend sur deux lignes : la première ligne est donc ignorée, et l’ancien format .xls nécessite le moteur xlrd :

import pandas as pd cl_df = pd.read_excel("Climate data.xls", engine="xlrd", skiprows=1)

Dériver les clés de jointure

Les noms de district et de secteur sont extraits des colonnes d’unités organisationnelles puis normalisés (la clé de secteur est ensuite combinée avec le district pour lever l’ambiguïté des noms de secteurs en double) :

cl_df["District"] = cl_df["orgunitlevel3"].str.split(" ").str[0] cl_df["Sector"] = cl_df["orgunitlevel5"].str.split(r"[ _-]").str[0].str.capitalize()

Renommer et sélectionner

cl_df["humidity"] = cl_df["RF001 Relative humidity (ERA5-Land)"] cl_df["Average_temperature"] = cl_df["TMP001 Air temperature (ERA5-Land)"] cl_df["Max_temperature"] = cl_df["TMP002 Max air temperature (ERA5-Land)"] cl_df["Min_temperature"] = cl_df["TMP005 Min temperature (ERA5-Land)"] cl_df["Rainfall"] = cl_df["RF003 Precipitation (ERA5-Land)"] climate_data = cl_df[["periodname", "Sector", "District", "Average_temperature", "Max_temperature", "Min_temperature", "Rainfall", "humidity"]] climate_data["periodname"] = pd.to_datetime(climate_data["periodname"], format="%B %Y")

Joindre aux secteurs

Le shapefile admin3 fournit la géométrie. Une clé combinée District + Sector des deux côtés rend la fusion sans ambiguïté :

merged = pd.merge(admin3, climate_data, on="Sector", how="inner")

Agréger à l’année

Les lignes mensuelles sont réduites à une température annuelle moyenne et à des précipitations totales par secteur, puis reconstruites en GeoDataFrame :

import geopandas as gpd agg = merged[merged["periodname"].dt.year == year_to_plot] g = (agg.groupby("adm_name", as_index=False) .agg({"geometry": "first", "Average_temperature": "mean", "Rainfall": "sum"})) gdf = gpd.GeoDataFrame(g, geometry="geometry", crs=merged.crs)

Standardisation des noms

L’étape de loin la plus sujette aux erreurs est la mise en correspondance des noms de secteurs des données climatiques avec le shapefile. L’orthographe varie d’un système à l’autre, et une clé sans correspondance fait silencieusement disparaître un secteur de la jointure interne. Les corrections connues sont appliquées explicitement :

Réconciliation des noms de secteursGeoPandasPython
Purpose

Aligner les noms de lieux des données climatiques avec le shapefile admin3 afin qu’aucun secteur ne soit perdu lors de la jointure.

When to use
  • Avant de fusionner tout jeu de données indexé par établissement avec les limites administratives
  • Chaque fois qu’une jointure interne renvoie moins de secteurs que prévu
Usage
# Shapefile side admin3["ADM3_EN"].replace("Mageregere", "Mageragere", inplace=True) admin3["ADM3_EN"].replace("Shyrongi", "Shyorongi", inplace=True) admin3["Sector"] = admin3["ADM2_EN"] + " " + admin3["ADM3_EN"] # Climate side climate_data["Sector"].replace("Ririma", "Rilima", inplace=True)
Caveats & gotchas
  • Une jointure interne masque les non-correspondances — comparez le nombre de lignes avant et après pour repérer les secteurs perdus
  • Ces corrections sont propres aux limites NISR de 2006 ; vérifiez-les avec le shapefile que vous chargez réellement
Related

Classes et rendu

La carte choroplèthe utilise des seuils de classes fixes et significatifs plutôt qu’un dégradé continu, afin que la carte se lise d’un coup d’œil. La température et les précipitations ont chacune leurs propres classes et leur propre palette (YlOrRd pour la température, Blues pour les précipitations) :

temp_bins = [0, 15, 17, 19, 22, gdf["Average_temperature"].max()] temp_labels = ["0-15", "15-17", "17-19", "19-22", "> 22"] precip_bins = [0, 200, 300, 500, 800, gdf["Rainfall"].max()] precip_labels = ["0-200", "200-300", "300-500", "500-800", "> 800"]

Chaque panneau trace la colonne de valeurs avec sa palette, superpose les limites admin1admin3 pour le contexte et construit une légende à partir des couleurs des classes. Voir la dernière cellule du notebook pour la figure complète à deux panneaux.

Cette image est régénérée par analysis/spatial-analysis/generate_figures.py, qui exécute Climate_maps.ipynb et écrit climate_two_panel_map.png en local ; elle est ensuite publiée sur Hugging Face (nhic/rwanda-spatial/charts/) par scripts/upload-spatial-to-hf.sh.

Dernière mise à jour le