ESA WorldCereal#

Mots-clés data used; WorldCereal, datasets; esa_worldcereal_temporarycrops, datasets; esa_worldcereal_activecropland, data used; esa_worldcereal_maize_main, datasets; esa_worldcereal_maize_active datasets; esa_worldcereal_maize_irrigation, datasets; esa_worldcereal_wintercereals

Aperçu#

Le projet ESA WorldCereal fournit un système cohérent à l’échelle mondiale, dérivé par satellite, pour surveiller l’étendue des terres cultivées, les types de cultures et les pratiques d’irrigation. Conçu pour la surveillance agricole saisonnière à une résolution de 10 mètres, le système utilise des données optiques et radar provenant de Sentinel-1 SAR et Sentinel-2 MSI, permettant des observations à haute fréquence et résilientes aux nuages à travers diverses zones agro-écologiques. L’initiative s’appuie sur des efforts de prototypage antérieurs et fournit désormais un système de traitement harmonisé et entièrement open-source (Agence spatiale européenne [ESA], 2025).

Les principaux résultats comprennent l’étendue annuelle des terres cultivées temporaires, les classifications saisonnières des types de cultures (par exemple, les céréales et le maïs), le statut d’irrigation et les couches de confiance associées. Ces produits sont disponibles à l’échelle mondiale mais sont particulièrement pertinents pour les régions confrontées à des défis de sécurité alimentaire, telles que l’Afrique subsaharienne et l’Asie du Sud. Les produits sont cartographiés à l’aide de zones agro-écologiques pour tenir compte des calendriers de plantation régionaux, et le système prend en charge la co-création de modèles personnalisés à l’aide de données de référence in-situ fournies par l’utilisateur.

Toutes les cartes sont fournies dans des grilles spatiales standardisées (EPSG:4326), avec des versions de sortie et des mesures de qualité validées par rapport aux observations au sol. La plateforme comprend également un module de données de référence mondiales, permettant le partage, la conservation et la récupération de données harmonisées de vérité terrain sur les cultures. Les améliorations continues de l’entraînement des modèles, de l’optimisation des algorithmes et de la correction atmosphérique améliorent la précision et la convivialité des produits au fil du temps.

Digital Earth Africa (DE Africa) héberge ces ensembles de données pour la région africaine, offrant un accès gratuit et ouvert aux données. Ce notebook montre comment charger les jeux de données WorldCereal dans l’environnement Sandbox de DE Africa.

Tableau récapitulatif

Code produit

Résolution spatiale

Période

esa_worldcereal_temporarycrops

10 m

2021

esa_worldcereal_activecropland

10 m

2021

esa_worldcereal_maize_main

10 m

2021

esa_worldcereal_maize_active

10 m

2021

esa_worldcereal_maize_irrigation

10 m

2021

esa_worldcereal_wintercereals

10 m

2021

esa_worldcereal_wintercereals_irrigation

10 m

2021

Mesure

Mesure

Terres cultivées temporaires (temporarycrops)

Terres cultivées actives (activecropland)

Maïs principal (maize_main)

Irrigation du maïs (maize_irrigation)

Céréales d’hiver (wintercereals)

Irrigation des céréales d’hiver (wintercereals_irrigation)

Classification binaire

Oui

Oui

Oui

Oui

Oui

Oui

Type de culture (maïs/céréales d’hiver)

Non

Non

Oui

Oui

Oui

Oui

Statut d’irrigation

Non

Non

Non

Oui

Non

Oui

Couche de confiance

Oui

Oui

Oui

Oui

Oui

Oui

Masque de zone agro-écologique (AEZ)

Oui

Oui

Oui

Oui

Oui

Oui

Description#

Dans ce notebook, nous chargerons les données esa_worldcereal_**** en utilisant dc.load()

Les sujets abordés comprennent :

  1. Inspection du produit esa_worldcereal_*** disponible dans le datacube

  2. Utilisation de la fonction dc.load() pour charger chaque donnée esa_worldcereal_****

  3. Tracé de esa_worldcereal_***


Commencer#

Pour exécuter cette analyse, exécutez toutes les cellules du bloc-notes, en commençant par la cellule « Charger les packages ».

Charger des paquets#

[1]:
%matplotlib inline



import numpy as np
import xarray as xr
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors
from matplotlib.colors import ListedColormap, BoundaryNorm
import geopandas as gpd
from odc.geo.geom import Geometry

import datacube
from deafrica_tools.plotting import display_map
from deafrica_tools.areaofinterest import define_area

Se connecter au datacube#

[2]:
dc = datacube.Datacube(app="WorldCereal")

Paramètres d’analyse#

La cellule suivante définit les paramètres qui déterminent la zone d’intérêt pour mener l’analyse.

Sélectionnez l’emplacement#

Pour définir la zone d’intérêt, deux méthodes sont disponibles :

  1. En spécifiant la latitude, la longitude et la zone tampon, ou en séparant les zones tampons de latitude et de longitude, cette méthode vous permet de définir une zone d’intérêt autour d’un point central. Vous pouvez saisir la latitude centrale, la longitude centrale et une valeur de zone tampon en degrés pour créer une zone carrée autour du point central. Par exemple, « lat = 10.338 », « lon = -1.055 » et « buffer = 0.1 » sélectionneront une zone avec un rayon de 0,1 degré carré autour du point avec les coordonnées « (10.338, -1.055) ».

    Vous pouvez également fournir des valeurs de tampon distinctes pour la latitude et la longitude d’une zone rectangulaire. Par exemple, « lat = 10.338 », « lon = -1.055 » et « lat_buffer = 0.1 » et « lon_buffer = 0.08 » sélectionneront une zone rectangulaire s’étendant sur 0,1 degré au nord et au sud et 0,08 degré à l’est et à l’ouest à partir du point « (10.338, -1.055) ».

    Pour des temps de chargement raisonnables, définissez la mémoire tampon sur « 0,1 » ou moins.

  2. By uploading a polygon as a GeoJSON or Esri Shapefile. If you choose this option, you will need to upload the geojson or ESRI shapefile into the Sandbox using Upload Files button 537ba91aae9d48db8c74b80ca5471101 in the top left corner of the Jupyter Notebook interface. ESRI shapefiles must be uploaded with all the related files (.cpg, .dbf, .shp, .shx). Once uploaded, you can use the shapefile or geojson to define the area of interest. Remember to update the code to call the file you have uploaded.

Pour utiliser l’une de ces méthodes, vous pouvez décommenter la ligne de code concernée et commenter l’autre. Pour commenter une ligne, ajoutez le symbole "#" avant le code que vous souhaitez commenter. Par défaut, la première option qui définit l’emplacement à l’aide de la latitude, de la longitude et du tampon est utilisée.

Si vous exécutez le notebook pour la première fois, conservez les paramètres par défaut ci-dessous. Cela démontrera le fonctionnement de l’analyse et fournira des résultats significatifs. L’emplacement par défaut est une zone avec divers types d’utilisation des terres et de couverture terrestre couvrant le Mozambique et le Malawi.

[3]:
# Method 1: Specify the latitude, longitude, and buffer)
aoi = define_area(lat=-15.7764, lon=35.8923, buffer=0.5)

# Method 2: Use a polygon as a GeoJSON or Esri Shapefile.
# aoi = define_area(vector_path='aoi.shp')

#Create a geopolygon and geodataframe of the area of interest
geopolygon = Geometry(aoi["features"][0]["geometry"], crs="epsg:4326")
geopolygon_gdf = gpd.GeoDataFrame(geometry=[geopolygon], crs=geopolygon.crs)

# Get the latitude and longitude range of the geopolygon
lats = (geopolygon_gdf.total_bounds[1], geopolygon_gdf.total_bounds[3])
lons = (geopolygon_gdf.total_bounds[0], geopolygon_gdf.total_bounds[2])

# Define the query
query = {
    'x': lons,
    'y': lats,
    'output_crs': 'epsg:6933',
}
[4]:
# The code below renders a map that can be used to view the region.
display_map(lons, lats)
[4]:
Make this Notebook Trusted to load map: File -> Trust Notebook

Accès aux données WorldCereal via DEAfrica#

1. Étendue des cultures temporaires#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_temporarycrops. Les informations de métadonnées se trouvent ici. Les données les plus récentes de 2021 sont utilisées dans cet exemple.

Le jeu de données présente deux couches : classification et confidence. La couche classification est une classification binaire entre les cultures temporaires, qui fait référence aux cultures cultivées pendant la saison concernée, tandis que la couche confidence indique la confiance avec laquelle chaque pixel est classé comme culture, en pourcentage.

[5]:
#load the data
esa_worldcereal_temporarycrops = dc.load(product='esa_worldcereal_temporarycrops',
                                measurements=['classification', 'confidence'],
                                resolution = (-10, 10),
                                time = ('2021'),
                                **query)

#Display the xrray dataset
esa_worldcereal_temporarycrops
[5]:
<xarray.Dataset> Size: 237MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-05-06T23:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 0 0 0 0 0 0 0 0 ... 0 0 0 0 0 0 0 0
    confidence      (time, y, x) uint8 119MB 73 73 73 73 81 ... 99 99 99 99 99
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

La cellule ci-dessous montre les couches classification et confidence pour la zone d’intérêt. En la comparant à l’image de référence produite par la fonction display_map() ci-dessus, nous pouvons voir que les zones couvertes par le lac Chilwa et la réserve forestière de la montagne de Mulanje sont classées dans d’autres classes de couverture terrestre (non cultivées) avec un niveau de confiance élevé, et que les terres cultivées sont dispersées dans d’autres zones avec des niveaux de confiance variables.

[6]:
classification = esa_worldcereal_temporarycrops.isel(time=-1)['classification']
confidence = esa_worldcereal_temporarycrops.isel(time=-1)['confidence']

# --- Plotting ---
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6), sharey=True)

# Plot 1: Binary Map
cmap_binary = mcolors.ListedColormap(['red', 'green', 'lightgray'])
bounds_binary = [-50, 50, 150, 300]  # Class boundaries
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im1 = classification.plot.imshow(
    ax=ax1, cmap=cmap_binary, norm=norm_binary, add_colorbar=False
)
ax1.set_title('Classification')
ax1.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Other Land Cover/Use', markerfacecolor='red', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Temporary Crops', markerfacecolor='green', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')

# Plot 2: Confidence Map
im2 = confidence.plot.imshow(
    ax=ax2, cmap='viridis', vmin=0, vmax=100, cbar_kwargs={'label': 'Confidence (%)'}
)
ax2.set_title('Confidence (0–100)')
ax2.set_ylabel('')

fig.suptitle('Temporary Cropland Extent 2021', fontsize=16, fontweight='bold')
plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_18_0.png

2. Terres cultivées actives#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_activecropland. Les informations de métadonnées se trouvent ici. Dans ce cas, après examen des métadonnées, nous pouvons voir que la couche de classification est encodée comme suit :

  • 0 : terres cultivées inactives

  • 100 : terres cultivées actives

  • 254 : pas de culture

  • 255 : pas de données

L’imagerie la plus récente de juillet 2021 est utilisée dans cet exemple.

[7]:
#load the data
esa_worldcereal_activecropland = dc.load(product='esa_worldcereal_activecropland',
                                measurements=['classification'],
                                resolution = (-10, 10),
                                time = ('2021'),
                                **query)

esa_worldcereal_activecropland
[7]:
<xarray.Dataset> Size: 119MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-07-05T11:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 254 254 254 254 ... 254 254 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

La répartition des terres cultivées dans la zone d’intérêt par défaut correspond à celle observée ci-dessus. En juillet 2021 (hiver dans la zone d’intérêt par défaut), la majorité des terres cultivées sont classées comme inactives.

[8]:
fig, ax = plt.subplots(figsize=(8, 6))

cmap_binary = mcolors.ListedColormap(['#FF7F7F', '#255F38', '#DEEDCF', 'lightgray'])
bounds_binary = [-0.5, 50, 150, 254.5, 300]
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im = esa_worldcereal_activecropland.isel(time=-1)['classification'].plot.imshow(
    ax=ax,
    cmap=cmap_binary,
    norm=norm_binary,
    add_colorbar=False
)

ax.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Inactive Cropland', markerfacecolor='#FF7F7F', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Active Cropland', markerfacecolor='#255F38', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Crop', markerfacecolor='#DEEDCF', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')


ax.set_title('Active Cropland Extent')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_22_0.png

3. Terres cultivées actives pendant la saison du maïs#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_maize_active. Les informations de métadonnées se trouvent ici. Le produit est défini comme une carte des terres cultivées actives pour la principale saison de maïs définie dans une région. Nous pouvons donc interpréter la classification des terres cultivées actives comme se référant à toutes les cultures actives, et pas seulement au maïs.

Après examen des métadonnées, nous constatons que le produit maïs actif est encodé comme suit :

  • 0 : terres cultivées inactives

  • 100 : terres cultivées actives

  • 254 : pas de culture

  • 255 : pas de données

L’imagerie la plus récente de janvier 2021 est utilisée dans cet exemple.

[9]:
#load the data
esa_worldcereal_maize_active = dc.load(product='esa_worldcereal_maize_active',
                                measurements=['classification'],
                                resolution = (-10, 10),
                                time = ('2021-06'),
                                **query)

esa_worldcereal_maize_active
[9]:
<xarray.Dataset> Size: 119MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-01-20T11:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 254 254 254 254 ... 254 254 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

En janvier 2021, il apparaît qu’une grande partie des terres cultivées était active.

[10]:
# Plot the xarray DataArray with custom colormap
fig, ax = plt.subplots(figsize=(8, 6))

cmap_binary = mcolors.ListedColormap(['#FF7F7F', '#255F38', '#DEEDCF', 'lightgray'])
bounds_binary = [-0.5, 50, 150, 254.5, 300]
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im = esa_worldcereal_maize_active.isel(time=-1)['classification'].plot.imshow(
    ax=ax,
    cmap=cmap_binary,
    norm=norm_binary,
    add_colorbar=False
)

# Custom colorbar setup with boundaries
ax.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Inactive Cropland', markerfacecolor='#FF7F7F', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Active Cropland', markerfacecolor='#255F38', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Crop', markerfacecolor='#DEEDCF', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')

ax.set_title('Extent of Active Cropland during the Maize Season')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_26_0.png

4. Terres cultivées en maïs de saison principale#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_maize_main. Ce produit fait référence à une carte des cultures de maïs pour la principale saison de maïs définie dans une région. Nous pouvons donc interpréter la carte comme se rapportant uniquement aux cultures de maïs. Les informations de métadonnées se trouvent ici.

  • 0 : terres cultivées inactives non-maïs

  • 100 : terres cultivées actives maïs

  • 254 : pas de culture

  • 255 : pas de données

L’imagerie la plus récente de janvier 2021 est utilisée dans cet exemple.

[11]:
#load the data
esa_worldcereal_maize_main = dc.load(product='esa_worldcereal_maize_main',
                                measurements=['classification','confidence'],
                                resolution = (-10, 10),
                                time = ('2021'),
                                **query)

esa_worldcereal_maize_main
[11]:
<xarray.Dataset> Size: 237MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-01-20T11:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 254 254 254 254 ... 254 254 254 254
    confidence      (time, y, x) uint8 119MB 247 247 247 247 ... 254 254 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

Nous pouvons voir que le maïs représente une grande proportion des terres cultivées actives, présentées ci-dessus, pour la principale saison de maïs. Nous pouvons supposer que le reste des terres cultivées actives qui ne sont pas du maïs pourrait être planté avec d’autres cultures d’été. Nous pourrions combiner ce produit esa_worldcereal_maize_main avec le produit esa_worldcereal_maize_active pour déterminer quelles zones sont actives et ne sont pas du maïs.

[12]:
classification = esa_worldcereal_maize_main.isel(time=-1)['classification']
confidence = esa_worldcereal_maize_main.isel(time=-1)['confidence']

# --- Plotting ---
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6), sharey=True)

# Plot 1: Binary Map
cmap_binary = mcolors.ListedColormap(['#FF7F7F', '#255F38', 'lightgray'])
bounds_binary = [-50, 50, 150, 255]  # Class boundaries
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im1 = classification.plot.imshow(
    ax=ax1, cmap=cmap_binary, norm=norm_binary, add_colorbar=False
)
ax1.set_title('Classification')
ax1.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Non-maize Cropland', markerfacecolor='#FF7F7F', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Maize Cropland', markerfacecolor='#255F38', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')

# Plot 2: Confidence Map
im2 = confidence.plot.imshow(
    ax=ax2, cmap='viridis', vmin=0, vmax=100, cbar_kwargs={'label': 'Confidence (%)'}
)
ax2.set_title('Confidence (0–100)')
ax2.set_ylabel('')

fig.suptitle('Main Maize Season Extent', fontsize=16, fontweight='bold')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_30_0.png

5. Étendue spatiale des terres cultivées irriguées pendant la saison du maïs#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_maize_irrigation. Les informations de métadonnées se trouvent ici. L’imagerie la plus récente est utilisée dans cet exemple. Le produit est spécifiquement conçu pour capturer toutes les cultures actives, qu’elles soient pluviales ou irriguées, cultivées pendant la principale saison de maïs. Voici les attributs du produit :

  • 0 : Pluvial → zones où les cultures dépendent uniquement des précipitations pour leur croissance.

  • 100 : Irrigué → zones où les cultures sont cultivées avec un apport d’irrigation supplémentaire.

  • 254 : pas de culture

  • 255 : pas de données

  • L’imagerie la plus récente de janvier 2021 est utilisée dans cet exemple.

[13]:
#load the data
esa_worldcereal_maize_irrigation = dc.load(product='esa_worldcereal_maize_irrigation',
                                measurements=['classification','confidence'],
                                resolution = (-10, 10),
                                time = ('2021'),
                                **query)

esa_worldcereal_maize_irrigation
[13]:
<xarray.Dataset> Size: 237MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-01-20T11:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 254 254 254 254 ... 254 254 254 254
    confidence      (time, y, x) uint8 119MB 248 248 248 248 ... 254 254 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

L’image ci-dessous montre les terres cultivées actives qui ont été irriguées pendant la saison du maïs ainsi que celles qui ont été pluviales. La carte de confiance fournit une assurance pour justifier le résultat, basée sur une échelle allant de 0 à 100 %

[14]:
classification = esa_worldcereal_maize_irrigation.isel(time=-1)['classification']
confidence = esa_worldcereal_maize_irrigation.isel(time=-1)['confidence']

# --- Plotting ---
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6), sharey=True)

# Plot 1: Binary Map
cmap_binary = mcolors.ListedColormap(['#FF7F7F', '#255F38', '#DEEDCF', 'lightgray'])
bounds_binary = [-0.5, 50, 150, 254.5, 300]
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im1 = classification.plot.imshow(
    ax=ax1, cmap=cmap_binary, norm=norm_binary, add_colorbar=False
)
ax1.set_title('Classification')
ax1.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Rainfed', markerfacecolor='#FF7F7F', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Irrigated', markerfacecolor='#255F38', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Crop', markerfacecolor='#DEEDCF', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')

# Plot 2: Confidence Map
im2 = confidence.plot.imshow(
    ax=ax2, cmap='viridis', vmin=0, vmax=100, cbar_kwargs={'label': 'Confidence (%)'}
)
ax2.set_title('Confidence (0–100)')
ax2.set_ylabel('')

fig.suptitle('Irrigated Cropland Extent during the Maize Season', fontsize=16, fontweight='bold')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_34_0.png

6. Terres cultivées en céréales d’hiver#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_wintercereals. Ce produit fait référence à une carte des céréales pour la principale saison céréalière définie dans une région. Nous pouvons donc interpréter la carte comme se rapportant uniquement aux cultures céréalières. Les informations de métadonnées se trouvent ici. Voici les attributs du produit :

  • 0 : Autre culture temporaire

  • 100 : Céréales d’hiver

  • 254 : Pas de culture

  • 255 : Pas de données

L’imagerie la plus récente de juillet 2021 est utilisée dans cet exemple.

[15]:
#load the data
esa_worldcereal_wintercereals = dc.load(product='esa_worldcereal_wintercereals',
                                measurements=['classification','confidence'],
                                resolution = (-10, 10),
                                time = ('2021'),
                                **query)

esa_worldcereal_wintercereals
[15]:
<xarray.Dataset> Size: 237MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-07-05T11:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 254 254 254 254 ... 254 254 254 254
    confidence      (time, y, x) uint8 119MB 249 249 249 249 ... 254 254 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

L’image ci-dessous montre les cultures de céréales d’hiver et d’autres cultures temporaires. La carte de confiance fournit une assurance pour justifier le résultat, sur une échelle allant de 0 à 100 %

[16]:
classification = esa_worldcereal_wintercereals.isel(time=-1)['classification']
confidence = esa_worldcereal_wintercereals.isel(time=-1)['confidence']

# --- Plotting ---
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6), sharey=True)

# Plot 1: Binary Map
cmap_binary = mcolors.ListedColormap(['#FF7F7F', '#255F38', '#DEEDCF', 'lightgray'])
bounds_binary = [-0.5, 50, 150, 254.5, 300]
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im1 = classification.plot.imshow(
    ax=ax1, cmap=cmap_binary, norm=norm_binary, add_colorbar=False
)
ax1.set_title('Classification')
ax1.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Other Temporary Crop', markerfacecolor='#FF7F7F', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Winter Cereals', markerfacecolor='#255F38', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Crop', markerfacecolor='#DEEDCF', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')

# Plot 2: Confidence Map
im2 = confidence.plot.imshow(
    ax=ax2, cmap='viridis', vmin=0, vmax=100, cbar_kwargs={'label': 'Confidence (%)'}
)
ax2.set_title('Confidence (0–100)')
ax2.set_ylabel('')

fig.suptitle('Winter Cereals Extent', fontsize=16, fontweight='bold')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_38_0.png

7. Terres cultivées en céréales principales irriguées#

La cellule ci-dessous montre comment charger le jeu de données à l’aide du code produit esa_worldcereal_wintercereals_irrigation. Ce produit fait référence à une carte de céréales irriguées pour la principale saison céréalière irriguée définie dans une région. Nous pouvons donc interpréter la carte comme se rapportant uniquement aux cultures céréalières. Les informations de métadonnées se trouvent ici.

  • 0 : Pluvial

  • 100 : Irrigué

  • 254 : Pas de culture

  • 255 : Pas de données

L’imagerie la plus récente de janvier 2021 est utilisée dans cet exemple.

[17]:
#load the data
esa_worldcereal_wintercereals_irrigation = dc.load(product='esa_worldcereal_wintercereals_irrigation',
                                measurements=['classification','confidence'],
                                resolution = (-10, 10),
                                time = ('2021'),
                                **query)

esa_worldcereal_wintercereals_irrigation
[17]:
<xarray.Dataset> Size: 237MB
Dimensions:         (time: 1, y: 12290, x: 9649)
Coordinates:
  * time            (time) datetime64[ns] 8B 2021-07-05T11:59:59.500000
  * y               (y) float64 98kB -1.926e+06 -1.926e+06 ... -2.049e+06
  * x               (x) float64 77kB 3.415e+06 3.415e+06 ... 3.511e+06 3.511e+06
    spatial_ref     int32 4B 6933
Data variables:
    classification  (time, y, x) uint8 119MB 254 254 254 254 ... 254 254 254 254
    confidence      (time, y, x) uint8 119MB 248 248 248 248 ... 254 254 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Visualisation des résultats#

L’image ci-dessous montre les exploitations céréalières qui ont été irriguées ainsi que celles qui ont été pluviales. La carte de confiance fournit une assurance pour justifier le résultat, basée sur une échelle allant de 0 à 100 %

[18]:
classification = esa_worldcereal_wintercereals_irrigation.isel(time=-1)['classification']
confidence = esa_worldcereal_wintercereals_irrigation.isel(time=-1)['confidence']

# --- Plotting ---
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(14, 6), sharey=True)

# Plot 1: Binary Map
cmap_binary = mcolors.ListedColormap(['#FF7F7F', '#255F38', '#DEEDCF', 'lightgray'])
bounds_binary = [-0.5, 50, 150, 254.5, 300]
norm_binary = mcolors.BoundaryNorm(bounds_binary, cmap_binary.N)

im1 = classification.plot.imshow(
    ax=ax1, cmap=cmap_binary, norm=norm_binary, add_colorbar=False
)
ax1.set_title('Classification')
ax1.legend(handles=[
    plt.Line2D([0], [0], marker='o', color='w', label='Rainfed', markerfacecolor='#FF7F7F', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='Irrigated', markerfacecolor='#255F38', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Crop', markerfacecolor='#DEEDCF', markersize=10),
    plt.Line2D([0], [0], marker='o', color='w', label='No Data', markerfacecolor='lightgray', markersize=10)
], loc='lower right')

# Plot 2: Confidence Map
im2 = confidence.plot.imshow(
    ax=ax2, cmap='viridis', vmin=0, vmax=100, cbar_kwargs={'label': 'Confidence (%)'}
)
ax2.set_title('Confidence (0–100)')
ax2.set_ylabel('')

fig.suptitle('Irrigated Cereal Extent', fontsize=16, fontweight='bold')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_42_0.png

Terres cultivées actives et inactives : Modèles d’irrigation du maïs et d’agriculture pluviale#

La cellule ci-dessous est conçue pour préparer et aligner les trois jeux de données WorldCereal (maïs principal, maïs irrigué et maïs actif) afin qu’ils puissent être fusionnés sans conflit. Pour ce faire, elle commence par renommer les variables qui se chevauchent (par exemple, en changeant « classification » dans le jeu de données sur le maïs principal en « maize_classification », « classification » dans le jeu de données sur l’irrigation en « irrigation_classification » et « classification » dans le jeu de données sur le maïs actif en « active_classification »), ce qui évite les problèmes de MergeError lorsque les jeux de données ont les mêmes noms de variables. Elle renomme également « confidence » dans le jeu de données sur le maïs principal en « maize_confidence » par souci de clarté.

Une fois renommés, les jeux de données sont fusionnés avec xr.merge(), produisant un xarray.Dataset unique et unifié (merge_data) contenant les trois couches alignées sur les mêmes coordonnées et dimensions. Ce jeu de données combiné permet d’effectuer des requêtes multicouches (par exemple, identifier des zones de maïs irrigué avec un niveau de confiance élevé ou distinguer les terres cultivées actives des terres inactives), garantissant que toutes les variables sont accessibles au même endroit pour une analyse rationalisée.

[19]:
#Renaming variables
esa_worldcereal_maize_main = esa_worldcereal_maize_main.rename({"classification": "maize_classification", "confidence": "maize_confidence"})
esa_worldcereal_maize_irrigation = esa_worldcereal_maize_irrigation.rename({"classification": "irrigation_classification", "confidence": "irrigation_confidence"})
esa_worldcereal_maize_active = esa_worldcereal_maize_active.rename({"classification": "active_classification"})

#Merging of the maize_main, maize_irrigation and maize_active
merge_data = xr.merge([esa_worldcereal_maize_main, esa_worldcereal_maize_irrigation, esa_worldcereal_maize_active])

#Display the Results
merge_data
[19]:
<xarray.Dataset> Size: 593MB
Dimensions:                    (time: 1, y: 12290, x: 9649)
Coordinates:
  * time                       (time) datetime64[ns] 8B 2021-01-20T11:59:59.5...
  * y                          (y) float64 98kB -1.926e+06 ... -2.049e+06
  * x                          (x) float64 77kB 3.415e+06 ... 3.511e+06
    spatial_ref                int32 4B 6933
Data variables:
    maize_classification       (time, y, x) uint8 119MB 254 254 254 ... 254 254
    maize_confidence           (time, y, x) uint8 119MB 247 247 247 ... 254 254
    irrigation_classification  (time, y, x) uint8 119MB 254 254 254 ... 254 254
    irrigation_confidence      (time, y, x) uint8 119MB 248 248 248 ... 254 254
    active_classification      (time, y, x) uint8 119MB 254 254 254 ... 254 254
Attributes:
    crs:           epsg:6933
    grid_mapping:  spatial_ref

Identification des classes de terres cultivées#

Dans cette section, nous utilisons le jeu de données WorldCereal fusionné (merge_data) pour diviser les terres cultivées en catégories significatives. En combinant les informations des couches classification du maïs, classification de l’irrigation et classification des terres cultivées actives, nous pouvons distinguer :

  • Maïs irrigué actif : Pixels classés comme maïs (maize_classification = 100) et irrigués (irrigation_classification = 100).

  • Maïs pluvial actif : Pixels classés comme maïs (maize_classification = 100) et pluviaux (irrigation_classification = 0).

  • Non-maïs irrigué actif : Pixels classés comme non-maïs (maize_classification = 0) mais irrigués (irrigation_classification = 100).

  • Non-maïs pluvial actif : Pixels classés comme non-maïs (maize_classification = 0) et pluviaux (irrigation_classification = 0).

  • Terres cultivées inactives : Pixels où des terres cultivées ont été identifiées (active_classification = 0), mais qui n’étaient pas actives pendant la saison.

Chacune de ces couches est extraite en appliquant des conditions logiques avec .where() au jeu de données fusionné.

[20]:
active_irrigated_maize = merge_data.isel(time=-1)['irrigation_classification'].where(
    (merge_data['irrigation_classification'] == 100) & (merge_data['maize_classification'] == 100)
)

active_rainfed_maize = merge_data.isel(time=-1)['irrigation_classification'].where(
    (merge_data['irrigation_classification'] == 0) & (merge_data['maize_classification'] == 100)
)

active_irrigated_non_maize = merge_data.isel(time=-1)['irrigation_classification'].where(
    (merge_data['irrigation_classification'] == 100) & (merge_data['maize_classification'] == 0)
)

active_rainfed_non_maize = merge_data.isel(time=-1)['irrigation_classification'].where(
    (merge_data['irrigation_classification'] == 0) & (merge_data['maize_classification'] == 0)
)

active_inactive_cropland = merge_data.isel(time=-1)['irrigation_classification'].where(
    (merge_data['active_classification'] == 0)
)

Visualisation des catégories de terres cultivées#

Dans cette étape, nous combinons les cinq couches de terres cultivées dérivées en une seule carte composite. Chaque pixel reçoit un code numérique en fonction de la catégorie à laquelle il appartient :

  • 0 → Maïs irrigué actif

  • 1 → Maïs pluvial actif

  • 2 → Non-maïs irrigué actif

  • 3 → Non-maïs pluvial actif

  • 4 → Terres cultivées inactives

Nous appliquons ensuite une palette de couleurs personnalisée pour afficher chaque classe dans une couleur distincte :

  • Rouge → Maïs irrigué actif

  • Vert → Maïs pluvial actif

  • Bleu → Non-maïs irrigué actif

  • Orange → Non-maïs pluvial actif

  • Violet → Terres cultivées inactives

Enfin, nous superposons ces catégories sur un seul graphique avec une légende, offrant ainsi une représentation visuelle claire du statut des terres cultivées et des pratiques de gestion de l’eau pour le maïs et d’autres cultures.

[21]:
# Create a base canvas using the first layer's shape
shape = active_irrigated_maize.shape
composite = np.full(shape, np.nan)

# Assign numeric codes for each class
composite = np.where(~np.isnan(active_irrigated_maize), 0, composite)
composite = np.where(~np.isnan(active_rainfed_maize), 1, composite)
composite = np.where(~np.isnan(active_irrigated_non_maize), 2, composite)
composite = np.where(~np.isnan(active_rainfed_non_maize), 3, composite)
composite = np.where(~np.isnan(active_inactive_cropland), 4, composite)

# Define colors and labels
colors = ['red', 'green', 'blue', 'orange', 'purple']
labels = [
    'Active Irrigated Maize',
    'Active Rainfed Maize',
    'Active Irrigated Non-Maize',
    'Active Rainfed Non-Maize',
    'Inactive Cropland'
]

cmap = ListedColormap(colors)

# Plot
fig, ax = plt.subplots(figsize=(6, 6))
im = ax.imshow(composite, cmap=cmap)

# Build a custom legend
handles = [plt.matplotlib.patches.Patch(color=colors[i], label=labels[i]) for i in range(len(colors))]
ax.legend(handles=handles, bbox_to_anchor=(1.05, 1), loc='upper left')

ax.set_title("Active and Inactive Cropland: Maize Irrigation and Rainfed Patterns")
ax.axis('off')

plt.tight_layout()
plt.show()
../../../_images/sandbox_notebooks_Datasets_World_Cereal_48_0.png

Conclusion#

Ce notebook montre comment charger le jeu de données WorldCereal dans la Sandbox de DE Africa. Les données peuvent être utilisées pour surveiller la dynamique des terres cultivées, détecter les changements saisonniers et comparer les modèles agricoles d’une région à l’autre. Elles peuvent également soutenir la création de jeux de données dérivés pour identifier les cultures de céréales et de maïs, aidant ainsi à suivre les tendances de productivité et à éclairer la planification de la sécurité alimentaire.


Références#

Agence spatiale européenne. (2025). Présentation de WorldCereal. ESA. https://www.esa.int/Applications/Observing_the_Earth/Introducing_World_Cereal


Informations Complémentaires#

Licence : Le code de ce carnet est sous licence Apache, version 2.0 <https://www.apache.org/licenses/LICENSE-2.0>. Les données de Digital Earth Africa sont sous licence Creative Commons par attribution 4.0 <https://creativecommons.org/licenses/by/4.0/>.

Contact : Si vous avez besoin d’aide, veuillez poser une question sur le canal Slack de DE Africa ou sur le GIS Stack Exchange en utilisant le tag open-data-cube (vous pouvez consulter les questions précédemment posées ici). Si vous souhaitez signaler un problème avec ce notebook, vous pouvez le faire sur Github.

Version de Datacube compatible :

[22]:
print(datacube.__version__)
1.8.20

Dernier test :

[23]:
from datetime import datetime
datetime.today().strftime('%Y-%m-%d')
[23]:
'2025-09-23'