un mot sur folium#
à télécharger
pour exécuter ce notebook sur votre ordi, commencez par télécharger le zip
la bibliothèque folium (https://python-visualization.github.io/folium/latest/) est un utilitaire qui permet de dessiner des cartes géographiques
elle est donc souvent utilisée en conjonction avec geopandas
les bases#
nous allons voir un exemple simplissime qui consiste à afficher des points sur une carte
une carte#
et pour commencer on doit créer un objet carte
import folium
# si on veut on peut ne rien préciser du tout
# mais nous on va se centrer sur Paris
PARIS = 48.856542, 2.347614
map = folium.Map(
location=PARIS,
zoom_start=5,
width=500,
height=300,
)
map
des zones#
on peut facilement afficher des zones; par exemple affichons les arrondissements de Paris
je cherche dans google avec les mots-clés “arrondissements de Paris shapefile”
et je tombe ici https://opendata.paris.fr/explore/dataset/arrondissements/export/
d’où je télécharge le fichier
arrondissements.zipque je range dans le dossierdata/
et après cela je peux faire tout simplement ceci
import geopandas as gpd
arrondissements = gpd.read_file("data/arrondissements.zip", encoding="utf-8")
# accessoirement ceci est une geo dataframe
type(arrondissements)
geopandas.geodataframe.GeoDataFrame
arrondissements.columns
Index(['n_sq_ar', 'c_ar', 'c_arinsee', 'l_ar', 'l_aroff', 'n_sq_co', 'surface',
'perimetre', 'geometry'],
dtype='object')
arrondissements.head(2)
| n_sq_ar | c_ar | c_arinsee | l_ar | l_aroff | n_sq_co | surface | perimetre | geometry | |
|---|---|---|---|---|---|---|---|---|---|
| 0 | 750000011 | 11 | 75111 | 11ème Ardt | Popincourt | 750001537 | 3.665442e+06 | 8282.011886 | POLYGON ((2.39624 48.85415, 2.39708 48.85308, ... |
| 1 | 750000013 | 13 | 75113 | 13ème Ardt | Gobelins | 750001537 | 7.149311e+06 | 11546.546526 | POLYGON ((2.37491 48.83801, 2.37698 48.8361, 2... |
# pour afficher cela
map = folium.Map(
location=PARIS,
zoom_start=12,
)
folium.GeoJson(
data=arrondissements,
).add_to(map)
map
naturellement on peut aussi, en compliquant un petit peu, mettre des couleurs différentes, ajouter des tooltips, etc..
par exemple:
# générateur de couleur
import random
def random_color():
def randbyte():
return f"{random.randint(0, 255):02x}"
return f"#{randbyte()}{randbyte()}{randbyte()}"
# on associe une couleur à chaque arrondissement
arrondissements['color'] = arrondissements.geometry.map(lambda x: random_color())
# pour ajouter des zones
def paris_map():
map = folium.Map(
location=PARIS,
zoom_start=11,
)
folium.GeoJson(
data=arrondissements,
style_function=lambda x: {"color": x["properties"]["color"]},
tooltip=folium.GeoJsonTooltip(
fields=["l_ar", "l_aroff"],
aliases=["nom", "label"],
)
).add_to(map)
return map
paris_map()
des marqueurs#
pour trouver des données à afficher je retoourne ici <opendata.paris.fr/explore/dataset/velib-disponibilite-en-temps-reel/export>
et cette fois je download au format GeoJson; les données sont mises à jour en temps réel, mais ce n’est pas important
velibs = gpd.read_file("data/velib-disponibilite-en-temps-reel.geojson")
velibs.head()
| stationcode | name | is_installed | capacity | numdocksavailable | numbikesavailable | mechanical | ebike | is_renting | is_returning | duedate | nom_arrondissement_communes | code_insee_commune | geometry | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 31104 | Mairie de Rosny-sous-Bois | OUI | 30 | 3 | 26 | 3 | 23 | OUI | OUI | 2023-10-30 14:23:05+00:00 | Rosny-sous-Bois | None | POINT (2.48658 48.87126) |
| 1 | 16107 | Benjamin Godard - Victor Hugo | OUI | 35 | 13 | 22 | 16 | 6 | OUI | OUI | 2023-10-30 14:21:48+00:00 | Paris | None | POINT (2.27572 48.86598) |
| 2 | 44015 | Rouget de L'isle - Watteau | OUI | 20 | 18 | 2 | 1 | 1 | OUI | OUI | 2023-10-30 14:20:28+00:00 | Vitry-sur-Seine | None | POINT (2.3963 48.77819) |
| 3 | 9020 | Toudouze - Clauzel | OUI | 21 | 16 | 5 | 1 | 4 | OUI | OUI | 2023-10-30 14:19:19+00:00 | Paris | None | POINT (2.33736 48.8793) |
| 4 | 12109 | Mairie du 12ème | OUI | 30 | 26 | 3 | 1 | 2 | OUI | OUI | 2023-10-30 14:23:57+00:00 | Paris | None | POINT (2.38755 48.84086) |
pour ajouter tous ces points, la démarche est à peu près la même que pour les arrondissements; sauf que si on le fait naïvement on tombe sur une erreur - apparemment folium n’aime pas les colonnes de type datetime64, on va l’enlever
# pour contourner une erreur signalée par folium avec les timestamps
# go figure...
if 'duedate' in velibs.columns:
velibs = velibs.drop(columns=['duedate'])
# on ne voit pas grand-chose avec le look par défaut
# trops de points, les marques sont trop grosses
map = paris_map()
folium.GeoJson(
data=velibs,
).add_to(map)
map
et ici aussi on peut affiner un peu et customiser le look de chaque point; on choisit de mettre un point avec une taille qui dépend du nombre de vélos disponibles
# pour ajouter des marques
map = paris_map()
folium.GeoJson(
data=velibs,
# on choisit le type de marker
marker=folium.CircleMarker(),
# et les attributs sont calculés ici
style_function=lambda x: dict(
color="black",
radius=1 if not x["properties"]["capacity"]
else 2 + 4 * (x["properties"]["numbikesavailable"]
/x["properties"]["capacity"])
),
# on peut aussi mettre des tooltips...
tooltip=folium.GeoJsonTooltip(
fields=['name', 'numbikesavailable', 'capacity'],
aliases=['nom', 'vélos dispos', 'total'],
),
).add_to(map)
map
on peut sauver la carte !#
une dernière feature très pratique, c’est qu’une fois la carte créée, on peut la sauver au format html standalone (plus besoin de python ni de jupyter pour l’utiliser, le fichier se charge dans un browser web)
# après l'avoir créé, ouvrez le fichier dans le browser
map.save("my-map.html")