Skip to content

Commit 102ce9f

Browse files
authored
Relecture Thomas, première partie (#438)
* relecture tutorial * correct typo * re read webscrapping * Update 03_geopandas_tutorial.qmd
1 parent 7091e59 commit 102ce9f

File tree

3 files changed

+45
-62
lines changed

3 files changed

+45
-62
lines changed

content/manipulation/03_geopandas_TP.qmd

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ une version très proche de ce TP est disponible dans [ce cours de `R`](https://
8484
Avant de se lancer dans le TD, il est nécessaire d'installer quelques
8585
librairies qui ne sont pas disponibles par défaut, dans l'environnement `Python`
8686
de base de la _data science_. Pour installer celles-ci depuis une
87-
cellule de _notebook_ `Jupyter`, le code suivant est à exécuter:
87+
cellule de _notebook_ `Jupyter`, le code suivant est à exécuter :
8888

8989
```{python}
9090
#| echo: true
@@ -98,15 +98,9 @@ cellule de _notebook_ `Jupyter`, le code suivant est à exécuter:
9898
!pip install topojson
9999
```
100100

101-
```{python}
102-
#| echo: false
103-
#| include: false
104-
!pip install topojson
105-
```
106-
107101
Après installations,
108102
les _packages_ à importer pour progresser
109-
dans ce chapitre sont les suivants:
103+
dans ce chapitre sont les suivants :
110104

111105
```{python}
112106
#| echo: true
@@ -747,7 +741,7 @@ Si on représente plutôt la capacité sous forme de densité, pour tenir compte
747741
petite_couronne_count['area'] = petite_couronne_count.area
748742
749743
petite_couronne_count['density'] = petite_couronne_count['area'].div(1e6)
750-
petite_couronne_count['density'] = petite_couronne_count['capacity']*petite_couronne_count['density']
744+
petite_couronne_count['density'] = petite_couronne_count['capacity']/petite_couronne_count['density']
751745
752746
aplat = petite_couronne_count.plot(
753747
column = "density", cmap="coolwarm", legend=True)

content/manipulation/03_geopandas_tutorial.qmd

Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -60,19 +60,14 @@ Il peut servir de pendant à celui-ci pour l'utilisateur de `R`.
6060

6161
Quelques installations préalables sont nécessaires :
6262

63-
```python
64-
#| output: false
63+
```{python}
64+
#| message : false
6565
!pip install pandas fiona shapely pyproj rtree # à faire obligatoirement en premier pour utiliser rtree ou pygeos pour les jointures spatiales
6666
!pip install contextily
6767
!pip install geopandas
6868
!pip install topojson
6969
```
7070

71-
```{python}
72-
#| echo: false
73-
!pip install topojson
74-
```
75-
7671
Pour être en mesure d'exécuter ce tutoriel, les imports suivants
7772
seront utiles.
7873

@@ -92,19 +87,19 @@ import matplotlib.pyplot as plt
9287

9388
**Le terme "données spatiales" désigne les données qui portent sur les caractéristiques géographiques des objets (localisation, contours, liens)**.
9489
Les caractéristiques géographiques des objets sont décrites à l'aide d'un **système de coordonnées**
95-
qui permettent une représentation dans un espace euclidien ($(x,y)$).
90+
qui permettent une représentation dans un espace euclidien $(x,y)$.
9691
Le passage de l'espace réel (la Terre, qui est une sphère) à l'espace plan
9792
se fait grâce à un **système de projection**. Voici quelques exemples
9893
de données spatiales :
9994

100-
* Une table décrivant des bâtiments, avec les coordonnées géographiques de chaque bâtiment;
101-
* Le découpage communal du territoire, avec le contour du territoire de chaque commune;
95+
* Une table décrivant des bâtiments, avec les coordonnées géographiques de chaque bâtiment ;
96+
* Le découpage communal du territoire, avec le contour du territoire de chaque commune ;
10297
* Les routes terrestres, avec les coordonnées décrivant leur parcours en 3 dimensions (longitude, latitude, altitude).
10398

10499
Les données spatiales rassemblent classiquement deux types de données :
105100

106-
1. des **données géographiques** (ou géométries): objets géométriques tels que des points, des vecteurs, des polygones, ou des maillages (*raster*). Exemple: la forme de chaque chaque commune, les coordonnées d'un bâtiment;
107-
2. des **données attributaires** (ou attributs): des mesures et des caractéristiques associés aux objets géométriques. Exemple: la population de chaque commune, le nombre de fenêtres et le nombre d'étages d'un bâtiment.
101+
1. des **données géographiques** (ou géométries) : objets géométriques tels que des points, des vecteurs, des polygones, ou des maillages (*raster*). Exemple: la forme de chaque commune, les coordonnées d'un bâtiment;
102+
2. des **données attributaires** (ou attributs) : des mesures et des caractéristiques associées aux objets géométriques. Exemple: la population de chaque commune, le nombre de fenêtres et le nombre d'étages d'un bâtiment.
108103

109104
**Les données spatiales sont fréquemment traitées à l'aide d'un système d'information géographique (SIG)**, c'est-à-dire un système d'information capable de stocker, d'organiser et de présenter des données alphanumériques spatialement référencées par des coordonnées dans un système de référence (CRS). `Python` dispose de fonctionnalités lui permettant de réaliser les mêmes tâches qu'un SIG (traitement de données spatiales, représentations cartographiques).
110105

@@ -119,11 +114,11 @@ DataFrame `Pandas` mais propose des méthodes adaptées au traitement des donné
119114

120115
Ainsi, grâce à `Geopandas`, on pourra effectuer des manipulations sur les attributs des données comme avec `pandas` mais on pourra également faire des manipulations sur la dimension spatiale des données. En particulier,
121116

122-
* Calculer des distances et des surfaces;
123-
* Agréger rapidement des zonages (regrouper les communes en département par exemple);
124-
* Trouver dans quelle commune se trouve un bâtiment à partir de ses coordonnées géographiques;
125-
* Recalculer des coordonnées dans un autre système de projection.
126-
* Faire une carte, rapidement et simplement
117+
* Calculer des distances et des surfaces ;
118+
* Agréger rapidement des zonages (regrouper les communes en département par exemple) ;
119+
* Trouver dans quelle commune se trouve un bâtiment à partir de ses coordonnées géographiques ;
120+
* Recalculer des coordonnées dans un autre système de projection ;
121+
* Faire une carte, rapidement et simplement.
127122

128123
::: {.cell .markdown}
129124
```{=html}
@@ -147,7 +142,7 @@ d'automatiser le traitement et la représentation des données. D'ailleurs,
147142

148143
### Résumé
149144

150-
En résumé, un objet `GeoPandas` comporte les éléments suivantes:
145+
En résumé, un objet `GeoPandas` comporte les éléments suivantes :
151146

152147
![](https://rgeo.linogaliana.fr/slides/img/sf.png)
153148

@@ -199,11 +194,11 @@ Un mauvais système de représentation
199194
fausse l'appréciation visuelle mais peut aussi entraîner des erreurs dans
200195
les calculs sur la dimension spatiale.
201196

202-
**Les systèmes de projection font l'objet de standards internationaux et sont souvent désignés par des codes dits codes EPSG**. Ce [site](https://epsg.io/) est un bon aide-mémoire. Les plus fréquents, pour les utilisateurs français, sont les suivants (plus d'infos [ici](https://geodesie.ign.fr/contenu/fichiers/documentation/SRCfrance.pdf)):
197+
**Les systèmes de projection font l'objet de standards internationaux et sont souvent désignés par des codes dits codes EPSG**. Ce [site](https://epsg.io/) est un bon aide-mémoire. Les plus fréquents, pour les utilisateurs français, sont les suivants (plus d'infos [ici](https://geodesie.ign.fr/contenu/fichiers/documentation/SRCfrance.pdf)) :
203198

204-
* `2154`: système de projection Lambert 93. Il s'agit du système de projection officiel. La plupart des données diffusées par l'administration pour la métropole sont disponibles dans ce système de projection.
205-
* `27572`: Lambert II étendu. Il s'agit de l'ancien système de projection officiel. Les données spatiales anciennes peuvent être dans ce format.
206-
* `4326`: WGS 84 ou système de pseudo-Mercator ou encore _Web Mercator_. Ce n'est en réalité pas un système de projection mais un système de coordonnées (longitude / latitude) qui permet simplement un repérage angulaire sur l'ellipsoïde. Il est utilisé pour les données GPS. Il s'agit du système le plus
199+
* `2154` : système de projection Lambert 93. Il s'agit du système de projection officiel. La plupart des données diffusées par l'administration pour la métropole sont disponibles dans ce système de projection.
200+
* `27572` : Lambert II étendu. Il s'agit de l'ancien système de projection officiel. Les données spatiales anciennes peuvent être dans ce format.
201+
* `4326` : WGS 84 ou système de pseudo-Mercator ou encore _Web Mercator_. Ce n'est en réalité pas un système de projection mais un système de coordonnées (longitude / latitude) qui permet simplement un repérage angulaire sur l'ellipsoïde. Il est utilisé pour les données GPS. Il s'agit du système le plus
207202
usuel, notamment quand on travaille avec des fonds de carte _web_.
208203

209204

@@ -374,23 +369,23 @@ Dans le système Lambert 93 (2154) :
374369

375370
Les formats les plus communs de données spatiales sont les suivants :
376371

377-
* _shapefile_ (`.shp`): format (**propriétaire**) le plus commun de données géographiques.
372+
* _shapefile_ (`.shp`) : format (**propriétaire**) le plus commun de données géographiques.
378373
La table de données (attributs) est stockée dans un fichier séparé des
379374
données spatiales. En faisant `geopandas.read_file("monfichier.shp")`, le
380-
package fait lui-même le lien entre les observations et leur représentation spatiale ;
375+
package fait lui-même le lien entre les observations et leur représentation spatiale.
381376
* _geopackage_ (`.gpkg`) : ce (relativement) nouveau format **libre** en un seul fichier également (lui recommandé par l'OGC) vise progressivement à se substituer au shapefile. Il est par exemple le format par défaut dans QGIS.
382377
* _geojson_ (`.json`) : ce format, non préconisé par l'OGC, est largement utilisé pour le développement _web_
383378
comme dans la librairie `leaflet.js`.
384379
La dimension spatiale est stockée dans le même fichier que les attributs.
385380
Ces fichiers sont généralement beaucoup plus légers que les *shapefiles* mais possèdent des limites s'agissant de gros jeux de données.
386-
* _topojson_ (`.json`): une variante du `geojson` qui se développe progressivement pour assister les visualisations _web_. Au lieu de stocker l'ensemble des points permettant de représenter une
381+
* _topojson_ (`.json`) : une variante du `geojson` qui se développe progressivement pour assister les visualisations _web_. Au lieu de stocker l'ensemble des points permettant de représenter une
387382
géométrie, seuls les arcs sont conservés. Cela allège substantiellement le poids du fichier et
388383
permet, avec une librairie adaptée, de reconstruire l'ensemble des contours géographiques.
389384

390385
Cette [page](https://si.ecrins-parcnational.com/blog/2020-02-geojson-shapefile-geopackage.html) compare plus en détail les principes formats de données géographiques.
391386
L'aide de [`Geopandas`](https://geopandas.org/io.html) propose des bouts de code en fonction des différentes situations dans lesquelles on se trouve.
392387

393-
### Exemple: récupérer les découpages territoriaux
388+
### Exemple : récupérer les découpages territoriaux
394389

395390
L'un des fonds de carte les plus fréquents qu'on utilise est celui des
396391
limites administratives des communes.
@@ -627,7 +622,7 @@ stations.crs
627622

628623
Les données sont dans le système de projection WGS84 qui est celui du
629624
système GPS. Celui-ci s'intègre bien avec les fonds de carte
630-
`Stamen`, `OpenStreetMap` ou `Google Maps`. En toute rigueur, si on
625+
`OpenStreetMap` ou `Google Maps`. En toute rigueur, si on
631626
désire effectuer certains calculs géométriques (mesurer des surfaces...), il est
632627
nécessaire de re-projeter les données dans un système qui préserve la géométrie
633628
(c'est le cas du Lambert 93).
@@ -647,7 +642,7 @@ fig,ax = plt.subplots(figsize=(10, 10))
647642
stations.sample(200).to_crs(3857).plot(ax = ax, color = 'red', alpha = 0.4, zorder=2)
648643
shp_communes.to_crs(3857).plot(ax = ax, zorder=1, edgecolor = "black", facecolor="none",
649644
color = None)
650-
#ctx.add_basemap(ax, source = ctx.providers.Stamen.Watercolor)
645+
ctx.add_basemap(ax, source = ctx.providers.OpenStreetMap.Mapnik)
651646
ax.set_axis_off()
652647
```
653648

@@ -701,7 +696,7 @@ fig,ax = plt.subplots(figsize=(10, 10))
701696
stations.sample(200).to_crs(3857).plot(ax = ax, color = 'red', alpha = 0.4, zorder=2)
702697
shp_communes.to_crs(3857).plot(ax = ax, zorder=1, edgecolor = "black", facecolor="none",
703698
color = None)
704-
#ctx.add_basemap(ax, source = ctx.providers.Stamen.Watercolor)
699+
ctx.add_basemap(ax, source = ctx.providers.OpenStreetMap.Mapnik)
705700
```
706701

707702
```{python}
@@ -722,7 +717,7 @@ fig,ax = plt.subplots(figsize=(10, 10))
722717
stations.sample(200).to_crs(3857).plot(ax = ax, color = 'red', alpha = 0.4, zorder=2)
723718
shp_communes.to_crs(3857).plot(ax = ax, zorder=1, edgecolor = "black", facecolor="none",
724719
color = None)
725-
#ctx.add_basemap(ax, source = ctx.providers.Stamen.Watercolor)
720+
ctx.add_basemap(ax, source = ctx.providers.OpenStreetMap.Mapnik)
726721
ax.set_axis_off()
727722
ax
728723
```
@@ -926,7 +921,7 @@ stations = stations.to_crs(2154)
926921
Concernant la gestion des projections avec `GeoPandas`,
927922
la [documentation officielle](https://geopandas.org/projections.html) est très bien
928923
faite. Elle fournit notamment l'avertissement suivant qu'il est
929-
bon d'avoir en tête:
924+
bon d'avoir en tête :
930925

931926
> Be aware that most of the time you don’t have to set a projection. Data loaded from a reputable source (using the geopandas.read_file() command) should always include projection information. You can see an objects current CRS through the GeoSeries.crs attribute.
932927
>
@@ -935,20 +930,20 @@ bon d'avoir en tête:
935930
![*Image empruntée à XKCD <https://xkcd.com/2256/> qu'on peut également trouver sur <https://blog.chrislansdown.com/2020/01/17/a-great-map-projection-joke/>*](https://imgs.xkcd.com/comics/bad_map_projection_south_america.png)
936931

937932

938-
Pour déterminer le système de projection d'une base de données, on peut vérifier l'attribut `crs`:
933+
Pour déterminer le système de projection d'une base de données, on peut vérifier l'attribut `crs` :
939934

940935
```{python}
941936
communes.crs
942937
```
943938

944939
Les deux principales méthodes pour définir le système de projection utilisé sont :
945940

946-
* **`df.set_crs`**: cette commande sert à préciser quel est le système de projection utilisé, c'est-à-dire comment les coordonnées *(x,y)* sont reliées à la surface terrestre. **Cette commande ne doit pas être utilisée pour transformer le système de coordonnées, seulement pour le définir**.
947-
* **`df.to_crs`**: **cette commande sert à projeter les points d'une géométrie dans une autre, c'est-à-dire à recalculer les coordonnées selon un autre système de projection.**
941+
* **`df.set_crs`** : cette commande sert à préciser quel est le système de projection utilisé, c'est-à-dire comment les coordonnées *(x,y)* sont reliées à la surface terrestre. **Cette commande ne doit pas être utilisée pour transformer le système de coordonnées, seulement pour le définir**.
942+
* **`df.to_crs`** : **cette commande sert à projeter les points d'une géométrie dans une autre, c'est-à-dire à recalculer les coordonnées selon un autre système de projection.**
948943

949944
Dans le cas particulier de production de carte avec un fond `OpenStreetMaps` ou une carte dynamique `leaflet`, il est nécessaire de dé-projeter les données (par exemple à partir du Lambert-93) pour atterrir dans le système non-projeté WGS 84 (code EPSG 4326). Ce site [dédié aux projections géographiques](https://epsg.io/) peut-être utile pour retrouver le système de projection d'un fichier où il n'est pas indiqué.
950945

951-
La définition du système de projection se fait de la manière suivante (:warning: avant de le faire, se souvenir de l'avertissement !):
946+
La définition du système de projection se fait de la manière suivante (:warning: avant de le faire, se souvenir de l'avertissement !) :
952947

953948
~~~python
954949
communes = communes.set_crs(2154)

content/manipulation/04a_webscraping_TP.qmd

Lines changed: 12 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -128,8 +128,8 @@ où le _web scraping_ est plus proche du comportement dans le _Far West_.
128128
### Les bonnes pratiques
129129

130130
La possibilité de récupérer des données par l'intermédiaire
131-
d'un robot ne signifie pas qu'on peut se permettre de n'être
132-
pas civilisé. En effet, lorsqu'il est non-maîtrisé, le
131+
d'un robot ne signifie pas qu'on peut se permettre de ne pas être
132+
civilisé. En effet, lorsqu'il est non-maîtrisé, le
133133
_webscraping_ peut ressembler à une attaque informatique
134134
classique pour faire sauter un site _web_ : le déni de service.
135135
Le cours d'[Antoine Palazzolo](https://inseefrlab.github.io/formation-webscraping/) revient
@@ -319,7 +319,7 @@ Pour être en mesure d'utiliser `Selenium`, il est nécessaire
319319
de faire communiquer `Python` avec un navigateur _web_ (Firefox ou Chromium).
320320
Le _package_ `webdriver-manager` permet de faire savoir à `Python`
321321
se trouve ce navigateur s'il est déjà installé dans un chemin standard.
322-
Pour l'installer, le code de la cellule ci-dessous peut être utilisé
322+
Pour l'installer, le code de la cellule ci-dessous peut être utilisé.
323323

324324
```{=html}
325325
</div>
@@ -338,7 +338,7 @@ nommé `webdriver-manager`:
338338
On va commencer doucement. Prenons une page _wikipedia_,
339339
par exemple celle de la Ligue 1 de football, millésime 2019-2020 : [Championnat de France de football 2019-2020](https://fr.wikipedia.org/wiki/Championnat_de_France_de_football_2019-2020). On va souhaiter récupérer la liste des équipes, ainsi que les url des pages Wikipedia de ces équipes.
340340

341-
Etape :one: : se connecter à la page wikipedia et obtenir le code source.
341+
Etape 1️⃣ : se connecter à la page wikipedia et obtenir le code source.
342342
Pour cela, le plus simple est d'utiliser le package `urllib` ou, mieux, `requests`.
343343
Nous allons ici utiliser la fonction `request` du _package_ `urllib`:
344344

@@ -353,7 +353,7 @@ request_text = request.urlopen(url_ligue_1).read()
353353
type(request_text)
354354
```
355355

356-
Etape :two: : utiliser le package BeautifulSoup
356+
Etape 2️⃣ : utiliser le package BeautifulSoup
357357
qui permet de rechercher efficacement
358358
les balises contenues dans la chaine de caractères
359359
renvoyée par la fonction `request`:
@@ -379,7 +379,7 @@ La methode `.find` ne renvoie que la première occurence de l'élément.
379379

380380
Pour vous en assurer vous pouvez :
381381

382-
- copier le bout de code source obtenu,
382+
- copier le bout de code source obtenu lorsque vous chercher une `table`,
383383
- le coller dans une cellule de votre notebook
384384
- et passer la cellule en _"Markdown"_
385385

@@ -434,7 +434,7 @@ Pour cela, nous allons procéder en 6 étapes:
434434
```
435435
:::
436436

437-
1️ Trouver le tableau
437+
1️⃣ Trouver le tableau
438438

439439
```{python}
440440
# on identifie le tableau en question : c'est le premier qui a cette classe "wikitable sortable"
@@ -448,7 +448,7 @@ print(tableau_participants)
448448
```
449449
:::
450450

451-
2️ Récupérer chaque ligne du tableau.
451+
2️⃣ Récupérer chaque ligne du tableau
452452

453453
On recherche d'abord toutes les lignes du tableau avec la balise `tr`
454454

@@ -474,7 +474,7 @@ print(rows[1])
474474

475475

476476

477-
3️ Nettoyer les sorties en ne gardant que le texte sur une ligne
477+
3️⃣ Nettoyer les sorties en ne gardant que le texte sur une ligne
478478

479479

480480
On va utiliser l'attribut `text` afin de se débarasser de toute la couche de HTML qu'on obtient à l'étape 2.
@@ -496,7 +496,7 @@ for ele in cols :
496496
print(ele.text.strip())
497497
```
498498

499-
4️ Généraliser sur toutes les lignes :
499+
4️⃣ Généraliser sur toutes les lignes :
500500

501501
```{python}
502502
for row in rows:
@@ -530,7 +530,7 @@ data_participants.head()
530530
```
531531

532532

533-
5️ Récupérer les en-têtes du tableau:
533+
5️⃣ Récupérer les en-têtes du tableau:
534534

535535
```{python}
536536
for row in rows:
@@ -557,7 +557,7 @@ columns_participants = [re.sub('\[ (\d+) \] ?', '', nom_col) for nom_col in colu
557557
columns_participants
558558
```
559559

560-
6️ Finalisation du tableau
560+
6️⃣ Finalisation du tableau
561561

562562
```{python}
563563
data_participants.columns = columns_participants[1:]
@@ -585,12 +585,6 @@ stade=[]
585585
latitude_stade=[]
586586
longitude_stade=[]
587587
588-
def dms2dd(degrees, minutes, seconds, direction):
589-
dd = float(degrees) + float(minutes)/60 + float(seconds)/(60*60);
590-
if direction == 'S' or direction == 'O':
591-
dd *= -1
592-
return dd;
593-
594588
url_list=["http://fr.wikipedia.org/wiki/Championnat_de_France_de_football_2019-2020", "http://fr.wikipedia.org/wiki/Championnat_de_France_de_football_de_Ligue_2_2019-2020"]
595589
596590
for url_ligue in url_list :

0 commit comments

Comments
 (0)