Cartographier des données linguistiques avec Python – 3

Les précédents articles consacrés à la cartographie de données linguistiques avec Python permettaient de créer une carte sur laquelle les informations d’un fichier CSV étaient représentées par une ou plusieurs séries de points. Dans certains cas, il est plus pertinent de ne pas représenter des points indépendants, mais plutôt une aire, une surface.

Voici comment faire, toujours en partant d’un fichier CSV (ou TSV) contenant une série de coordonnées géographiques.

Prérequis

Je vous conseille la lecture préalable des précédents articles “Cartographie de données linguistiques avec Python”, puisque je ne réexpliquerai pas ce qui y a déjà été détaillé.

Comme d’habitude, le code (Python 3) sera mis à disposition dans un notebook Jupyter. En plus de folium et csv, il faudra également importer Polygon de la librairie shapely.geometry1.

Construction du code Python

Le code pour obtenir la carte présentée ici est librement téléchargeable sous forme de notebook Jupyter, sur Gitlab. Le fichier d’entrée utilisé est également disponible, de même que la carte HTML produite en sortie.
La carte peut être directement consultée en ligne sur cette page (sans téléchargement).

L’objectif sera d’obtenir une carte semblable à celle-ci (voir en ligne) :

Le fichier TSV pris en entrée, hmon1336.tsv, a déjà été présenté ici.

Fond de carte

La mise en place du fond de carte “vide” reste la même, il s’agit d’une instance de folium.Map() dont les paramètres sont à définir selon le projet. Dans l’exemple, la carte est nommée ma_carte.

Contrairement aux représentations avec des marqueurs/points, la méthode employée ici ne nécessite pas de déclarer une couche de données avant d’y ajouter les données du fichier CSV/TSV.

Transformer les coordonnées en un polygone

Le fichier d’entrée est lu via une instance de csv.DictReader(), ici appelée lecteur2. Chaque ligne de lecteur comporte des coordonnées géographiques, dont les index sont ligne['Longitude'] et ligne['Latitude'].

Il faut maintenant créer une instance d’objet Polygon() à partir de l’ensemble de ces coordonnées. Contrairement à un point, un polygone ne se construit pas à partir d’une seule paire de coordonnées longitude/latitude mais à partir d’une série d’au moins trois paires de coordonnées. Concrètement, l’objet Polygon() va prendre en paramètre une liste de tuples (longitude,latitude). Ici, la compréhension de liste permet de déclarer un objet Polygon() à partir de la liste des tuples de l’ensemble des lignes du fichier d’éntrée :

hmon1336_contour = Polygon([(float(ligne['Longitude']), float(ligne['Latitude'])) for ligne in lecteur])

Les variables étant nommées de façon assez explicite, on comprend sans problème qu’on constitue ici une liste comportant un tuple (float(ligne['Longitude']), float(ligne['Latitude'])) pour chaque ligne du lecteur. Il est indispensable de convertir ligne['Longitude'] et ligne['Latitude'] en float, puisque sinon les valeurs des coordonnées seraient lues comme des chaînes de caractères.

La variable hmon1336_contour correspond maintenant à un polygone dont voici la forme3 :

Au vu de cet aperçu, il est évident qu’ajouter ce polygone à la carte tel quel ne serait pas du tout satisfaisant.

À titre informatif, voici comment apparaîtrait ce polygone sur la carte.

Les objets Polygon() de shapely.geometry ont une propriété convex_hull, définie comme suit dans la documentation :

Returns a representation of the smallest convex Polygon containing all the points in the object unless the number of points in the object is less than three. For two points, the convex hull collapses to a LineString; for 1, a Point.

(documentation shapely)

Ce ne sera bien sûr pas d’une grande précision, mais cette propriété va permettre de corriger la forme du polygone de façon extrêmement simple.

hmon1336_ch = hmon1336_contour.convex_hull

Appeler hmon1336_ch pour prévisualiser la forme du nouveau polygone permet d’obtenir ceci :

Il a été tracé sur la base des quatre points les plus à l’extérieur du polygone d’origine. C’est tout à fait visible sur cette carte où les deux polygones sont superposés l’un sur l’autre4 :

Ajouter le polygone à la carte

Ce polygone “rectifié” peut maintenant être ajouté à la carte. Pour ce faire, j’ai ici choisi d’utiliser une couche GeoJSON, soit une instance d’objet folium.GeoJson() qui va prendre le polygone (= la variable hmon1336_ch) en paramètre. Il ne faut pas oublier de nommer la couche de données qui sera ainsi créée, en particulier si un layer control doit être mis en place par la suite. Donc, au minimum :

folium.GeoJson(
    hmon1336_ch,
    name='Hmong-Mien (surface)',
).add_to(ma_carte)

Dans l’exemple présenté dans le notebook, j’ai ajouté également des options pour modifier l’aspect graphique du polygone (avec la fonction lambda style_function) et un tooltip qui affichera le texte “Langues hmong-mien” lors du survol du polygone.

Une couche contenant le tracé du polygone a été ajoutée à la carte. L’opération peut être répétée autant de fois que nécessaire, et il est bien sûr possible de faire cohabiter des couches de points et des couches de polygones. Si les couches de données sont nombreuses, il est toujours possible de filtrer lesquelles faire apparaître afin de ne pas nuire à la lisibilité de l’ensemble sans perdre d’information.

Si vous avez suivi le notebook sans y apporter de modification, vous avez obtenu un fichier intitulé carte_hmong-mien_polygone.html contenant cette carte (code source).

Citer ce billet : “Cartographier des données linguistiques avec Python – 3”, par Alexander Delaporte. Publié sur Tekipaki le 18/02/2021. Lien : https://tekipaki.hypotheses.org/1414.
  1. from shapely.geometry import Polygon []
  2. Le fonctionnement de csv.DictReader() est expliqué dans cet article. []
  3. Dans le notebook, une fois que l’objet Polygon() est instancié et associé à la variable hmon1336_contour, il est possible d’afficher l’aperçu de la forme du polygone simplement en appelant la variable hmon1336_contour. []
  4. Cette carte n’a été éditée que pour la comparaison et n’a pas grand intérêt par ailleurs. Elle ne figure pas dans le notebook, mais il est facile de la reconstituer à partir des variables hmon1336_contour et hmon1336_ch. []

Auteur/autrice : Alexander Delaporte

Ingénieur d'études au Centre de recherches linguistiques sur l'Asie Orientale

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée.

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.

Rechercher dans OpenEdition Search

Vous allez être redirigé vers OpenEdition Search