Introduction au traçage
Produits utilisés : ls8_sr
Prérequis : Les utilisateurs de ce bloc-notes doivent avoir une compréhension de base de :
Comment exécuter un Jupyter notebook
Inspection des produits et mesures disponibles en Afrique DE <02_Products_and_measurements.ipynb>`__
Comment charger des données depuis DE Africa <03_Loading_data.ipynb>`__
Mots-clés guide du débutant; visualisation, visualisation; guide du débutant, données utilisées; landsat 8, visualisation; mesures, visualisation; pas de temps, visualisation; cartes couleur, paquet python; matplotlib
Aperçu
La visualisation des données est un élément important du travail avec les données d’observation de la Terre. Le package Python « xarray » fournit une gamme d’options de traçage de données simples qui permettent aux utilisateurs de générer rapidement des tracés simples à partir d’ensembles de données multidimensionnels. Pour générer des tracés plus complexes et informatifs à partir de données chargées depuis Digital Earth Africa (DE Africa), le référentiel DE Africa Notebooks fournit également un module de traçage personnalisé avec des fonctionnalités supplémentaires faciles à utiliser.
Description
Ce bloc-notes d’introduction montre comment visualiser les données satellite de Digital Earth Africa renvoyées par l’exécution d’une requête Datacube. Le bloc-notes présente les méthodes de traçage « xarray » couramment utilisées, ainsi que les fonctions personnalisées fournies dans « deafrica_tools.plotting ».
Les sujets abordés dans ce carnet incluent :
Affichez votre zone d’intérêt avant d’interroger le datacube
Interrogation du datacube et chargement des données
Tracé de données à bande unique (par exemple, une bande satellite unique)
Sélection et traçage de pas de temps individuels
Tracé de plusieurs pas de temps
Personnaliser l’apparence du tracé
Traçage d’images à trois bandes en vraies ou fausses couleurs
Traçage de pas de temps uniques
Tracé de plusieurs pas de temps
Personnaliser l’apparence du tracé
Commencer
Pour exécuter cette introduction au traçage des données chargées à partir du datacube, exécutez toutes les cellules du bloc-notes en commençant par la cellule « Charger les packages ». Pour obtenir de l’aide sur l’exécution des cellules du bloc-notes, reportez-vous au bloc-notes Jupyter Notebooks.
Charger des paquets
Nous exécutons d’abord « %matplotlib inline », qui garantit que les figures sont tracées correctement dans le notebook Jupyter.
Nous devons ensuite charger le package « datacube », qui nous permet de charger des données.
Le traçage des données nécessite des fonctions que nous pouvons importer depuis « deafrica_tools.plotting ». Pour ce bloc-notes, nous avons besoin de « rgb » et « display_map ». Nous pouvons importer les deux sur une seule ligne en séparant les noms par une virgule.
[1]:
%matplotlib inline
import datacube
from deafrica_tools.plotting import rgb, display_map
Se connecter au datacube
Nous nous connectons ensuite à la base de données Datacube afin de pouvoir charger les données DE Africa.
[2]:
dc = datacube.Datacube(app="04_Plotting")
Paramètres d’analyse
Les variables suivantes sont requises pour établir une requête pour ce notebook:
lat_range: la plage de latitude à analyser (par exemple,(11,72, 11,52)). Pour des temps de chargement raisonnables, maintenez cette plage à environ 0,1 degré ou moins.lon_range: la plage de longitude à analyser (par exemple,(-15,63, -15,43)). Pour des temps de chargement raisonnables, maintenez cette plage à environ 0,1 degré ou moins.time_range: la plage de dates à analyser (par exemple("2018-01-01", "2018-03-30")).
[3]:
lat_range = (11.72, 11.52)
lon_range = (-15.63, -15.43)
time_range = ("2017-01-01", "2017-03-30")
Afficher l’emplacement demandé
Avant d’exécuter une requête et d’extraire et d’analyser des données, il est utile de vérifier que votre emplacement est correct. La fonction display_map() affiche la zone sélectionnée sous la forme d’un rectangle rouge sur une carte interactive. En cliquant sur n’importe quel point de la carte, les coordonnées de latitude et de longitude de ce point s’affichent.
[4]:
display_map(x=lon_range, y=lat_range)
[4]:
Interroger et afficher les données
Les variables déterminées ci-dessus sont utilisées ici pour interroger le datacube DE Africa en utilisant la fonction dc.load() et charger les données introduites dans le Carnet de données de chargement. Ce carnet utilise la réflectance de surface Landsat 8 ls8_sr.
[5]:
ds = dc.load(product="ls8_sr",
measurements=['blue','green','red','nir','swir_1','swir_2'],
x=lon_range,
y=lat_range,
time=time_range,
output_crs='EPSG:6933',
resolution=(-30, 30))
print(ds)
<xarray.Dataset>
Dimensions: (time: 6, y: 834, x: 644)
Coordinates:
* time (time) datetime64[ns] 2017-01-06T11:22:16.948666 ... 2017-03...
* y (y) float64 1.485e+06 1.485e+06 1.485e+06 ... 1.46e+06 1.46e+06
* x (x) float64 -1.508e+06 -1.508e+06 ... -1.489e+06 -1.489e+06
spatial_ref int32 6933
Data variables:
blue (time, y, x) uint16 10396 10397 10394 10404 ... 8291 8258 8208
green (time, y, x) uint16 11703 11698 11703 11714 ... 9794 9747 9688
red (time, y, x) uint16 11823 11831 11837 11834 ... 8373 8320 8321
nir (time, y, x) uint16 8996 8994 8995 8990 ... 8092 8062 8051 8037
swir_1 (time, y, x) uint16 7614 7613 7627 7626 ... 8550 8559 8543 8519
swir_2 (time, y, x) uint16 7542 7530 7532 7535 ... 8449 8449 8444 8421
Attributes:
crs: EPSG:6933
grid_mapping: spatial_ref
Tracé d’images à bande unique
Le package « xarray » fournit des méthodes intégrées pour tracer des variables de données ou des mesures individuelles. Par exemple, nous pourrions vouloir créer un tracé pour une seule mesure comme la bande satellite « swir_1 » dans les données que nous avons chargées ci-dessus.
Pour ce faire, nous devons d’abord accéder à la bande que nous recherchons en tant que « xarray.DataArray » (pour réviser la différence entre les objets « xarray.Dataset » et « xarray.DataArray », reportez-vous au bloc-notes « Chargement des données <03_Loading_data.ipynb> ») :
[6]:
print(ds.swir_1)
<xarray.DataArray 'swir_1' (time: 6, y: 834, x: 644)>
array([[[ 7614, 7613, 7627, ..., 13610, 13829, 14045],
[ 7622, 7623, 7629, ..., 13587, 13795, 14460],
[ 7610, 7638, 7626, ..., 13435, 13630, 14045],
...,
[ 7594, 7610, 7668, ..., 7672, 7664, 7673],
[ 7575, 7593, 7634, ..., 7678, 7679, 7674],
[ 7586, 7578, 7617, ..., 7679, 7668, 7666]],
[[ 7571, 7583, 7581, ..., 11822, 11993, 12371],
[ 7575, 7582, 7619, ..., 11779, 12010, 12242],
[ 7591, 7594, 7613, ..., 11777, 11988, 12195],
...,
[ 8898, 9121, 9137, ..., 11705, 11537, 11535],
[ 9029, 9085, 9107, ..., 11766, 11709, 11734],
[ 9010, 9052, 9094, ..., 11885, 11799, 11796]],
[[ 9024, 9018, 9010, ..., 14730, 15078, 15485],
[ 9016, 9022, 9025, ..., 14663, 14844, 15442],
[ 9014, 9020, 9037, ..., 14547, 15005, 15308],
...,
...
...,
[ 8147, 8131, 8121, ..., 8488, 8549, 8608],
[ 8124, 8118, 8110, ..., 8483, 8515, 8581],
[ 8131, 8078, 8081, ..., 8484, 8514, 8583]],
[[ 8565, 8563, 8570, ..., 14624, 15405, 15539],
[ 8575, 8586, 8583, ..., 15189, 15669, 15273],
[ 8588, 8576, 8579, ..., 14797, 15825, 15656],
...,
[ 8383, 8296, 8291, ..., 8447, 8464, 8441],
[ 8369, 8285, 8295, ..., 8457, 8436, 8432],
[ 8362, 8277, 8288, ..., 8453, 8429, 8448]],
[[ 8497, 8421, 8415, ..., 14707, 15239, 15847],
[ 8461, 8422, 8394, ..., 15361, 15931, 16456],
[ 8461, 8401, 8383, ..., 15271, 16247, 16153],
...,
[ 8526, 8531, 8578, ..., 8492, 8542, 8536],
[ 8517, 8531, 8558, ..., 8516, 8528, 8544],
[ 8510, 8504, 8539, ..., 8559, 8543, 8519]]], dtype=uint16)
Coordinates:
* time (time) datetime64[ns] 2017-01-06T11:22:16.948666 ... 2017-03...
* y (y) float64 1.485e+06 1.485e+06 1.485e+06 ... 1.46e+06 1.46e+06
* x (x) float64 -1.508e+06 -1.508e+06 ... -1.489e+06 -1.489e+06
spatial_ref int32 6933
Attributes:
units: 1
nodata: 0
crs: EPSG:6933
grid_mapping: spatial_ref
Sélection et traçage d’un seul pas de temps
Vous pouvez voir dans l’en-tête de l’objet que ce « xarray.DataArray » contient des données pour six pas de temps (c’est-à-dire « <xarray.DataArray “swir_1” (time: 6, y: 834, x: 644)> »). Pour créer un tracé pour un seul pas de temps, nous devons le sélectionner à l’aide de l’une des options suivantes :
.isel(): Cela signifie « sélection d’index » et nous permet de sélectionner facilement des pas de temps individuels à partir d’un ensemble de données en fournissant le numéro de l’observation que nous voulons. Le comptage en Python commence à 0, donc pour sélectionner le premier pas de temps dansxarray.DataArray, nous pouvons spécifier.isel(time=0):
[7]:
first_timestep = ds.swir_1.isel(time=0)
print(first_timestep)
<xarray.DataArray 'swir_1' (y: 834, x: 644)>
array([[ 7614, 7613, 7627, ..., 13610, 13829, 14045],
[ 7622, 7623, 7629, ..., 13587, 13795, 14460],
[ 7610, 7638, 7626, ..., 13435, 13630, 14045],
...,
[ 7594, 7610, 7668, ..., 7672, 7664, 7673],
[ 7575, 7593, 7634, ..., 7678, 7679, 7674],
[ 7586, 7578, 7617, ..., 7679, 7668, 7666]], dtype=uint16)
Coordinates:
time datetime64[ns] 2017-01-06T11:22:16.948666
* y (y) float64 1.485e+06 1.485e+06 1.485e+06 ... 1.46e+06 1.46e+06
* x (x) float64 -1.508e+06 -1.508e+06 ... -1.489e+06 -1.489e+06
spatial_ref int32 6933
Attributes:
units: 1
nodata: 0
crs: EPSG:6933
grid_mapping: spatial_ref
.sel(): Cela nous permet de sélectionner des données en utilisant des étiquettes de coordonnées réelles telles quetime. Par exemple, dans la section Coordinates, nous pouvons sélectionner le premier pas de temps (c’est-à-dire l’observation du 6 janvier 2017) à partir dexarray.DataArrayen spécifiant.sel(time='2017-01-06'):
[8]:
first_timestep = ds.swir_1.sel(time='2017-01-06')
print(first_timestep)
<xarray.DataArray 'swir_1' (time: 1, y: 834, x: 644)>
array([[[ 7614, 7613, 7627, ..., 13610, 13829, 14045],
[ 7622, 7623, 7629, ..., 13587, 13795, 14460],
[ 7610, 7638, 7626, ..., 13435, 13630, 14045],
...,
[ 7594, 7610, 7668, ..., 7672, 7664, 7673],
[ 7575, 7593, 7634, ..., 7678, 7679, 7674],
[ 7586, 7578, 7617, ..., 7679, 7668, 7666]]], dtype=uint16)
Coordinates:
* time (time) datetime64[ns] 2017-01-06T11:22:16.948666
* y (y) float64 1.485e+06 1.485e+06 1.485e+06 ... 1.46e+06 1.46e+06
* x (x) float64 -1.508e+06 -1.508e+06 ... -1.489e+06 -1.489e+06
spatial_ref int32 6933
Attributes:
units: 1
nodata: 0
crs: EPSG:6933
grid_mapping: spatial_ref
Nous pouvons maintenant utiliser la méthode .plot() pour tracer les données swir1 pour notre pas de temps sélectionné :
[9]:
first_timestep.plot()
[9]:
<matplotlib.collections.QuadMesh at 0x7fd997ef6230>
Tracé de plusieurs pas de temps
Il est souvent utile de produire des tracés pour une seule mesure au fil du temps, par exemple pour comparer les changements entre les observations par satellite ou les ensembles de données récapitulatives. Pour tracer plusieurs images, nous pouvons ignorer l’étape isel() ci-dessus et tracer directement l’intégralité de xarray.DataArray.
Pour représenter graphiquement plusieurs pas de temps dans une figure, nous devons indiquer à la fonction .plot() de placer chaque pas de temps dans une colonne différente. Nous pouvons le faire en spécifiant .plot(col="time") :
[10]:
ds.swir_1.plot(col="time")
[10]:
<xarray.plot.facetgrid.FacetGrid at 0x7fd98df63940>
Remarque : ce type de tracé est appelé « traçage à facettes ». Pour plus d’informations, reportez-vous à la documentation xarray <http://xarray.pydata.org/en/stable/plotting.html#faceting>`__
Personnaliser l’apparence du tracé
Vous remarquerez peut-être que les tracés ci-dessus sont sombres et difficiles à voir clairement. Pour améliorer l’apparence des tracés « xarray », vous pouvez utiliser l’argument « robust=True » pour optimiser les couleurs des tracés en coupant les valeurs extrêmes ou les valeurs aberrantes. Cela utilisera les 2e et 98e percentiles des données pour calculer les limites de couleur :
[11]:
ds.swir_1.plot(col="time", robust=True)
[11]:
<xarray.plot.facetgrid.FacetGrid at 0x7fd98dc32590>
Nous pouvons également facilement utiliser des cartes/styles de couleurs personnalisés pour visualiser nos données à l’aide du paramètre « cmap ».
Lors du choix d’une carte de couleurs pour un graphique, il est important de choisir un ensemble de couleurs qui sont perçues logiquement par l’œil humain. Les meilleures cartes de couleurs sont « perceptuellement uniformes » : ces cartes de couleurs augmentent logiquement des couleurs sombres aux couleurs claires, où des augmentations égales de luminosité/obscurité correspondent à des changements égaux dans les valeurs des données. Certaines cartes de couleurs perceptuellement uniformes sont les suivantes :
"viridis", "plasma", "inferno", "magma", "cividis"
Remarque : pour en savoir plus sur les cartes de couleurs perceptuellement uniformes dans la visualisation des données, reportez-vous à la documentation matplotlib.
Il est également important de prendre en compte le daltonisme lors de la sélection d’une carte de couleurs. « xarray » prend en charge de nombreuses cartes de couleurs de la famille de cartes de couleurs « colorbrewer » qui sont optimisées pour le daltonisme. Vous pouvez utiliser l’outil interactif en ligne <http://colorbrewer2.org> pour parcourir toutes les cartes de couleurs disponibles, ou choisir l’une des options courantes suivantes :
"Greys", "Purples", "Blues", "Greens", "Oranges", "Reds",
"YlOrBr", "YlOrRd", "OrRd", "PuRd", "RdPu", "BuPu",
"GnBu", "PuBu", "YlGnBu", "PuBuGn", "BuGn", "YlGn"
Pour une liste complète des cartes de couleurs disponibles, vous pouvez vous référer à cette liste.
Par exemple, pour tracer nos données avec la carte de couleurs « magma » perceptuellement uniforme :
[12]:
ds.swir_1.plot(col="time", robust=True, cmap="magma")
[12]:
<xarray.plot.facetgrid.FacetGrid at 0x7fd98da58df0>
Traçage d’images RVB en vraies ou fausses couleurs
Bien que « xarray » facilite le traçage d’images à bande unique, le traçage d’une image couleur à trois bandes semblable à une photo est moins simple.
Pour faciliter cette opération, le référentiel « deafrica-sandbox-notebooks » fournit une fonction « rgb() » personnalisée conçue pour tracer des images à trois bandes. La fonction « rgb() » mappe trois variables de données/mesures de l’ensemble de données chargé aux canaux rouge, vert et bleu qui sont utilisés pour créer une image à trois couleurs.
Les mesures « rouge », « vert » et « bleu » fournies par un ensemble de données produiront une image en vraies couleurs (semblable à la façon dont les humains voient le paysage). Les mesures « nir », « rouge » et « vert » ou tout autre ensemble de trois bandes satellites fournies par un ensemble de données produiront une image en fausses couleurs. Vous pouvez en apprendre davantage sur le rendu des couleurs ici <https://en.wikipedia.org/wiki/False_color#True_color>`__.
La fonction rgb() peut donc être utilisée pour visualiser les données renvoyées par une requête. Elle nécessite au minimum les données suivantes :
ds:L’objetxarray.Dataset« bandes : » trois bandes à afficher (il doit s’agir de mesures trouvées dans l’ensemble de données)
index:Le pas de temps à afficher, la valeur par défaut est0
Tracer un pas de temps unique
La dimension temporelle de votre « xarray.Dataset » décrit le nombre d’intervalles de temps existant pour votre emplacement pendant la période de temps que vous avez indiquée. Dans la fonction « rgb() », la variable « index » demande quel intervalle de temps vous souhaitez afficher (similaire à l’exemple « isel() » ci-dessus). N’oubliez pas : le comptage en Python commence à 0, donc pour afficher l’intervalle de temps le plus ancien, définissez « index=0 » :
[13]:
# View a red, green, blue (true colour) image of the first timestep
rgb(ds, bands=["red", "green", "blue"], index=0)
En modifiant les bandes d’entrée, nous pouvons tracer une image en fausses couleurs qui peut fournir différentes informations sur un paysage. Cette combinaison de bandes (swir_1, nir, green) met en valeur la végétation en croissance en vert et l’eau en bleu profond :
[14]:
# View a swir_1, nir, green (false colour) image of the first timestep
rgb(ds, bands=['swir_1', 'nir', 'green'], index=0)
Tracé de plusieurs pas de temps
Comme indiqué dans l’exemple de bande unique ci-dessus <#Plotting-multiple-timesteps>`__, il peut être utile de visualiser plusieurs pas de temps dans un seul tracé (par exemple pour comparer les changements au fil du temps).
La fonction rgb() vous permet de le faire en fournissant une liste de plusieurs images à tracer en utilisant index=[X, X, ...]. Par exemple, nous pouvons tracer la première et la cinquième image de notre ensemble de données en utilisant index=[0, 4] (en gardant à l’esprit que le comptage en Python commence à 0) :
[15]:
# View a true colour image for the first and fith timesteps
rgb(ds, bands=['red', 'green', 'blue'], index=[0, 4])
Il est également possible d’utiliser rgb() pour tracer tous les pas de temps dans un ensemble de données en utilisant la syntaxe col="time" que nous démontrons dans l’exemple de bande unique ci-dessus <#Plotting-multiple-timesteps>`__ :
[16]:
# Plot all timesteps in the dataset
rgb(ds, bands=['red', 'green', 'blue'], col="time")
Personnaliser l’apparence du tracé
Par défaut, rgb() génère des tracés avec robust=True pour améliorer l’apparence des images en supprimant les 2% de pixels les plus sombres et les plus clairs, en utilisant les 2e et 98e percentiles des données pour calculer les limites de couleur.
Si cette valeur par défaut donne de mauvais résultats, l’étirement des couleurs du tracé peut être personnalisé à l’aide du paramètre « percentile_stretch ». Cela vous permet de découper les valeurs minimales et maximales les plus extrêmes de l’ensemble de données, afin d’améliorer le contraste et l’apparence du tracé.
Par exemple, en spécifiant « percentile_stretch=[0.05, 0.95] », vous supprimerez les 5 % de pixels les plus sombres et les plus clairs, en concentrant l’étirement des couleurs sur les 90 % restants des valeurs les moins extrêmes :
[17]:
rgb(ds,
bands=['red', 'green', 'blue'],
index=0,
percentile_stretch=[0.05, 0.95])
Étapes suivantes recommandées
Pour des informations plus avancées sur l’utilisation de Jupyter Notebooks ou JupyterLab, vous pouvez explorer la page de documentation de JupyterLab.
Pour continuer à travailler sur les cahiers de ce guide du débutant, les cahiers suivants sont conçus pour être travaillés dans l’ordre suivant :
Tracé (ce carnet)
Une fois que vous avez terminé les didacticiels ci-dessus, rejoignez les utilisateurs avancés pour explorer :
Le répertoire « Datasets » du référentiel, où vous pouvez explorer en profondeur les produits DE Africa.
Le répertoire « Code fréquemment utilisé », qui contient un livre de recettes de techniques et méthodes courantes pour l’analyse des données DE Africa.
Le répertoire « Exemples du monde réel », qui fournit des flux de travail plus complexes et des études de cas d’analyse.
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 poster une question sur le canal Slack Open Data Cube <http://slack.opendatacube.org/>`__ ou sur le GIS Stack Exchange en utilisant la balise open-data-cube (vous pouvez consulter les questions posées précédemment ici). Si vous souhaitez signaler un problème avec ce bloc-notes, vous pouvez en déposer un sur Github.
Version de Datacube compatible :
[18]:
print(datacube.__version__)
1.8.15
Dernier test :
[19]:
from datetime import date
print(date.today())
2023-08-11