Introduction to cartography with Python

Mapping is an excellent way of disseminating knowledge about data, even to audiences unfamiliar with statistics. This chapter looks at the challenge of mapping and how you can use Python to build maps.

Visualisation
Exercice
Author

Lino Galiana

Published

2025-03-19

If you want to try the examples in this tutorial:
View on GitHub Onyxia Onyxia Open In Colab
Compétences à l’issue de ce chapitre

1 Introduction

Cartography is one of the oldest forms of graphical representation of information. Historically confined to military and administrative uses or navigation-related information synthesis, cartography has, at least since the 19th century, become one of the preferred ways to represent information. It was during this period that the color-shaded map, known as the choropleth map, began to emerge as a standard way to visualize geographic data.

According to Chen et al. (2008), the first representation of this type was proposed by Charles Dupin in 1826 Figure 1.1 to illustrate literacy levels across France. The rise of choropleth maps is closely linked to the organization of power through unitary political entities. For instance, world maps often use color shades to represent nations, while national maps use administrative divisions (regions, departments, municipalities, as well as states or Länder).

Figure 1.1: The first choropleth map by Dupin (1826)

The emergence of choropleth maps during the 19th century marks an important shift in cartography, transitioning from military use to political application. No longer limited to depicting physical terrain, maps began to represent socioeconomic realities within well-defined administrative boundaries.

With the proliferation of geolocated data and the increasing use of data-driven decision-making, it has become crucial for data scientists to quickly create maps. This chapter, complementing the one on spatial data, offers exercises to explore the key principles of data visualization through cartography using Python.

Note

Creating high-quality maps requires time but also thoughtful decision-making. Like any graphical representation, it is essential to consider the message being conveyed and the most appropriate means of representation.
Cartographic semiology, a scientific discipline focusing on the messages conveyed by maps, provides guidelines to prevent misleading representations—whether intentional or accidental.

Some of these principles are outlined in this cartographic semiology guide from Insee. They are also summarized in this guide.

This presentation by Nicolas Lambert, using numerous examples, explores key principles of cartographic dataviz.

This chapter will first introduce some basic functionalities of Geopandas for creating static maps. To provide context to the presented information, we will use official geographic boundaries produced by IGN. We will then explore maps with enhanced contextualization and multiple levels of information, illustrating the benefits of using interactive libraries based on JavaScript, such as Folium.

1.1 Data Used

Throughout this chapter, we will use several datasets to illustrate different types of maps:

  • Population counts;
  • Departmental boundaries of metropolitan France;
  • Municipal boundaries of Finistère;
  • Forest cover in the Landes department;
  • The location of Vélib’ stations;

1.2 Prerequisite installations

Before getting started, a few packages need to be installed:

# Sur colab
1!pip install pandas fiona shapely pyproj rtree geopandas
1
Ces librairies sont utiles pour l’analyse géospatiale (cf. chapitre dédié)

We will primarily need Pandas and GeoPandas for this chapter.

import pandas as pd
import geopandas as gpd

2 First Maps to Understand the Spatial Coverage of Your Data

We will use cartiflette, which simplifies the retrieval of administrative basemaps from IGN. This package is an interministerial project designed to provide a simple Python interface for obtaining official IGN boundaries.

First, we will retrieve the departmental boundaries:

from cartiflette import carti_download

departements = carti_download(
    values="France",
    crs=4326,
    borders="DEPARTEMENT",
    vectorfile_format="geojson",
    filter_by="FRANCE_ENTIERE_DROM_RAPPROCHES",
    source="EXPRESS-COG-CARTO-TERRITOIRE",
    year=2022,
)

These data bring the DROM closer to mainland France, as explained in one of the cartiflette tutorials and as Exercise 1 will allow us to verify.

Exercise 1 aims to ensure that we have correctly retrieved the desired boundaries by simply visualizing them. This should be the first reflex of any geodata scientist.

Exercise 1: Representing Boundaries with GeoPandas Methods
  1. Use the plot method on the departements dataset to check the spatial extent. What projection do the displayed coordinates suggest? Verify using the crs method.
  2. Reproject the data to Lambert 93 (EPSG: 2154) and create the same map.
  3. Using appropriate matplotlib options, create a map with black boundaries, a white background, and no axes.
  4. Create the same map for the municipalities of Finistère.

The map of the departments, without modifying any options, looks like this:

The displayed coordinates suggest WGS84, which can be verified using the crs method:

<Geographic 2D CRS: EPSG:4326>
Name: WGS 84
Axis Info [ellipsoidal]:
- Lat[north]: Geodetic latitude (degree)
- Lon[east]: Geodetic longitude (degree)
Area of Use:
- name: World.
- bounds: (-180.0, -90.0, 180.0, 90.0)
Datum: World Geodetic System 1984 ensemble
- Ellipsoid: WGS 84
- Prime Meridian: Greenwich

If we convert to Lambert 93 (the official system for mainland France), we obtain a different extent, which is supposed to be more accurate for the mainland (but not for the relocated DROM, since, for example, French Guiana is actually much larger).

And of course, we can easily reproduce the failed maps from the chapter on GeoPandas, for example, if we apply a transformation designed for North America:

departements.to_crs(5070).plot()

If we create a slightly more aesthetically pleasing map, we get:

And the same for Finistère:

These maps are simple, yet they already rely on implicit knowledge. They require familiarity with the territory. When we start coloring certain departments, recognizing which ones have extreme values will require a good understanding of French geography. Likewise, while it may seem obvious, nothing in our map of Finistère explicitly states that the department is bordered by the ocean. A French reader would see this as self-evident, but a foreign reader, who may not be familiar with the details of our geography, would not necessarily know this.

To address this, we can use interactive maps that allow:

  • Displaying contextual information when hovering over or clicking on an element of the map.
  • Displaying a basemap with contextual information such as transport networks, localities, or natural boundaries.

For this, we will retain only the data corresponding to an actual spatial extent, excluding our zoom on Île-de-France and the DROM.

departements_no_duplicates = (
  departements
1  .drop_duplicates(subset = "INSEE_DEP")
)
departements_hexagone = (
  departements_no_duplicates
2  .loc[~departements['INSEE_DEP'].str.startswith("97")]
)
1
On retire le zoom sur l’Île de France
2
On ne garde que la France hexagonale

We successfully obtain the hexagon:

departements_hexagone.plot()

For the next exercise, we will need a few additional variables. First, the geometric center of France, which will help us position the center of our map.

minx, miny, maxx, maxy = departements_hexagone.total_bounds
center = [(miny + maxy) / 2, (minx + maxx) / 2]

We will also need a dictionary to provide Folium with information about our map parameters.

style_function = lambda x: {
1    'fillColor': 'white',
    'color': 'black',     
    'weight': 1.5,        
    'fillOpacity': 0.0   
}
1
In fact, this will allow for a transparent layer by combining it with the fillOpacity parameter set to 0%.

style_function is an anonymous function that will be used in the exercise.

Information that appears when hovering over an element is called a tooltip in web development terminology.

import folium
tooltip = folium.GeoJsonTooltip(
    fields=['LIBELLE_DEPARTEMENT', 'INSEE_DEP', 'POPULATION'],
    aliases=['Département:', 'Numéro:', 'Population:'],
    localize=True
)

For the next exercise, the GeoDataFrame must be in the Mercator projection. Folium requires data in this projection because it relies on navigation basemaps, which are designed for this representation. Typically, Folium is used for local visualizations where the surface distortion caused by the Mercator projection is not problematic.

For the next exercise, where we will represent France as a whole, we are slightly repurposing the library. However, since France is still relatively far from the North Pole, the distortion remains a small trade-off compared to the benefits of interactivity.

Exercise 2: Creating a First Interactive Map with Folium
  1. Create the base layer using the center object and set zoom_start to 5.
  2. Update it using our departements_hexagone dataset and the parameters style_function and tooltip.

Here is the base layer from question 1:

Make this Notebook Trusted to load map: File -> Trust Notebook

And once formatted, this gives us the map:

Make this Notebook Trusted to load map: File -> Trust Notebook

When hovering over the above map, some contextual information appears. This allows for different levels of information: at first glance, the data is spatially represented, while further exploration reveals secondary details that aid understanding but are not essential.

These initial exercises illustrated a situation where only the polygon boundaries are represented. This type of map is useful for quickly situating a dataset in space, but it does not provide additional information. To achieve that, it will be necessary to use the tabular data associated with the spatial dimension.

3 Representing Data: A First Example with a Forest Cover Map

In this section, we will create a map of the Landes forest cover using the BD Forêt dataset produced by IGN. The goal is no longer just to display the boundaries of the area of interest but to represent information about it using data from a GeoDataFrame.

Since BD Forêt is somewhat large in shapefile format, we suggest retrieving it in a more compressed format: geopackage.

foret = gpd.read_file(
  "https://minio.lab.sspcloud.fr/projet-formation/diffusion/r-geographie/landes.gpkg"
)

Nous allons aussi créer un masque pour les contours du département:

landes = (
  departements
  .loc[departements["INSEE_DEP"] == "40"].to_crs(2154)
)
Exercise 3: First Choropleth Map

Create a map of the forest cover in Landes using data previously imported from the BD Forêt dataset. You can add the department boundaries to provide context for this map.

This map can be created using Geopandas and matplotlib or with plotnine (see previous chapter).

As seen on the map (Figure 3.1), the Landes department is heavily forested. This makes sense since two-thirds of the department are covered, which can be verified with the following calculation[^landes-epsg-en]:

f"Part du couvert forestier dans les Landes: {float(foret.area.sum()/landes.area):.0%}"
/tmp/ipykernel_6203/849176039.py:1: FutureWarning:

Calling float on a single element Series is deprecated and will raise a TypeError in the future. Use float(ser.iloc[0]) instead
'Part du couvert forestier dans les Landes: 65%'
Figure 3.1: Couvert forestier des Landes

Here, the map is quite clear and conveys a relatively readable message. Of course, it does not provide details that might interest curious viewers (e.g., which specific localities are particularly forested), but it does offer a synthetic view of the studied phenomenon.

4 Introduction to Choropleth Maps

The previous exercise allowed us to create a solid color map. This naturally leads us to choropleth maps, where color shading is used to represent socioeconomic information.

We will use population data available from the datasets retrieved via cartiflette1. As an exercise, we will create a choropleth map styled in a vintage look, reminiscent of the early maps of Dupin (1826).

Exercise 4: A First Population Map

The goal of this exercise is to enhance the information presented on the departmental map.

  1. Quickly generate a map of the departments, coloring them according to the POPULATION variable.

    This map presents several issues:

    • If you are familiar with French geography, you should notice an unusual shape, as if the east-west axis were excessively stretched. This happens because the map needs to be reprojected into Lambert 93.
    • It is difficult to read due to several factors: continuous gradient, non-normal distribution of the variable, suboptimal legend, etc.

    The next questions aim to improve this step by step.

  2. Recreate this map using the Lambert 93 projection.

  3. Discretize the POPULATION variable into 4 classes using quantile-based discretization, then recreate the map.

  4. Normalize the population by the area of each department (in km²) by creating a new variable using .area.div(1e6)2.

  5. Choose a vintage grayscale color palette.

The first question produces a map that looks like this:

It is already improved by using a projection suited for the territory, Lambert 93 (question 2):

The map below, after discretization (question 3), already provides a more accurate representation of population inequalities. We can see the “diagonal of emptiness” starting to emerge, which is expected in a population map.

However, one of the problems with choropleth maps is that they give disproportionate visual weight to large areas. This issue was particularly highlighted in election maps with the visual “Land doesn’t vote, people do” (see the 2024 European elections version).

While we cannot completely eliminate this issue—doing so would require switching to a different type of visualization, such as proportional circles—we can mitigate the effect of area on our variable of interest by representing density (population per km² rather than total population).

We obtain the following map when representing population density instead of total population:

This already provides a more accurate picture of population distribution across France. However, the default desigual color palette does not help much in capturing the nuances. Using a gradient color palette, which considers the ordinal nature of our data, results in a more readable map (question 5):

This is already better. However, to create an even more effective map, a more suitable discretization method should be chosen. This is an important iterative process that requires multiple skill sets, including statistics, sociology or economics (depending on the type of information represented), and computer science. In short, the typical skill set of a data scientist.

5 Representing Sub-Municipal Data

Until now, we have worked with data where simply displaying administrative boundaries was sufficient for context. Now, let’s focus on a case where having a contextual basemap becomes crucial: sub-municipal maps.

For this, we will represent the locations of Vélib’ stations. These are available as open data from the Paris City Hall website.

import geopandas as gpd

velib_data = "https://opendata.paris.fr/explore/dataset/velib-emplacement-des-stations/download/?format=geojson&timezone=Europe/Berlin&lang=fr"
stations = gpd.read_file(velib_data)
Skipping field coordonnees_geo: unsupported OGR type: 3

If we directly plot them using the plot method, we lack context:

stations.plot()

It is even impossible to determine whether we are actually in Paris. We can attempt to associate our data with administrative boundaries to confirm that we are indeed in the Paris region.

The first step is to retrieve the boundaries of Parisian districts and neighboring municipalities, which can be easily done using cartiflette:

from cartiflette import carti_download

# 1. Fonds communaux
contours_villes_arrt = carti_download(
    values = ["75", "92", "93", "94"],
    crs = 4326,
    borders="COMMUNE_ARRONDISSEMENT",
    filter_by="DEPARTEMENT",
    source="EXPRESS-COG-CARTO-TERRITOIRE",
    year=2022)

# 2. Départements 
departements = contours_villes_arrt.dissolve("INSEE_DEP")

If we now use this mask to provide context to the data, we can be reassured about the nature of the data.

ax = stations.sample(200).plot(color = "red")
contours_villes_arrt.boundary.plot(ax=ax, edgecolor="k", linewidth=.5)
departements.boundary.plot(ax=ax, edgecolor="blue", linewidth=1)
ax.set_axis_off()

Parisians will easily recognize their city because they are familiar with the spatial organization of this metropolitan area. However, for readers unfamiliar with it, this map will be of little help. The ideal solution is to use Folium’s contextual basemap.

To avoid cluttering the map, it is useful to leverage Folium’s interactive features, allowing the user to navigate the map and display an appropriate amount of information based on the visible window. For this, Folium includes a very handy MarkerCluster functionality.

Thus, we can create the desired map as follows:

Make this Notebook Trusted to load map: File -> Trust Notebook

Additional References

Informations additionnelles

environment files have been tested on.

Latest built version: 2025-03-19

Python version used:

'3.12.6 | packaged by conda-forge | (main, Sep 30 2024, 18:08:52) [GCC 13.3.0]'
Package Version
affine 2.4.0
aiobotocore 2.21.1
aiohappyeyeballs 2.6.1
aiohttp 3.11.13
aioitertools 0.12.0
aiosignal 1.3.2
alembic 1.13.3
altair 5.4.1
aniso8601 9.0.1
annotated-types 0.7.0
anyio 4.8.0
appdirs 1.4.4
archspec 0.2.3
asttokens 2.4.1
attrs 25.3.0
babel 2.17.0
bcrypt 4.2.0
beautifulsoup4 4.12.3
black 24.8.0
blinker 1.8.2
blis 1.2.0
bokeh 3.5.2
boltons 24.0.0
boto3 1.37.1
botocore 1.37.1
branca 0.7.2
Brotli 1.1.0
bs4 0.0.2
cachetools 5.5.0
cartiflette 0.0.2
Cartopy 0.24.1
catalogue 2.0.10
cattrs 24.1.2
certifi 2025.1.31
cffi 1.17.1
charset-normalizer 3.4.1
chromedriver-autoinstaller 0.6.4
click 8.1.8
click-plugins 1.1.1
cligj 0.7.2
cloudpathlib 0.21.0
cloudpickle 3.0.0
colorama 0.4.6
comm 0.2.2
commonmark 0.9.1
conda 24.9.1
conda-libmamba-solver 24.7.0
conda-package-handling 2.3.0
conda_package_streaming 0.10.0
confection 0.1.5
contextily 1.6.2
contourpy 1.3.1
cryptography 43.0.1
cycler 0.12.1
cymem 2.0.11
cytoolz 1.0.0
dask 2024.9.1
dask-expr 1.1.15
databricks-sdk 0.33.0
dataclasses-json 0.6.7
debugpy 1.8.6
decorator 5.1.1
Deprecated 1.2.14
diskcache 5.6.3
distributed 2024.9.1
distro 1.9.0
docker 7.1.0
duckdb 1.2.1
en_core_web_sm 3.8.0
entrypoints 0.4
et_xmlfile 2.0.0
exceptiongroup 1.2.2
executing 2.1.0
fastexcel 0.11.6
fastjsonschema 2.21.1
fiona 1.10.1
Flask 3.0.3
folium 0.17.0
fontawesomefree 6.6.0
fonttools 4.56.0
fr_core_news_sm 3.8.0
frozendict 2.4.4
frozenlist 1.5.0
fsspec 2023.12.2
geographiclib 2.0
geopandas 1.0.1
geoplot 0.5.1
geopy 2.4.1
gitdb 4.0.11
GitPython 3.1.43
google-auth 2.35.0
graphene 3.3
graphql-core 3.2.4
graphql-relay 3.2.0
graphviz 0.20.3
great-tables 0.12.0
greenlet 3.1.1
gunicorn 22.0.0
h11 0.14.0
h2 4.1.0
hpack 4.0.0
htmltools 0.6.0
httpcore 1.0.7
httpx 0.28.1
httpx-sse 0.4.0
hyperframe 6.0.1
idna 3.10
imageio 2.37.0
importlib_metadata 8.6.1
importlib_resources 6.5.2
inflate64 1.0.1
ipykernel 6.29.5
ipython 8.28.0
itsdangerous 2.2.0
jedi 0.19.1
Jinja2 3.1.6
jmespath 1.0.1
joblib 1.4.2
jsonpatch 1.33
jsonpointer 3.0.0
jsonschema 4.23.0
jsonschema-specifications 2024.10.1
jupyter-cache 1.0.0
jupyter_client 8.6.3
jupyter_core 5.7.2
kaleido 0.2.1
kiwisolver 1.4.8
langchain 0.3.20
langchain-community 0.3.9
langchain-core 0.3.45
langchain-text-splitters 0.3.6
langcodes 3.5.0
langsmith 0.1.147
language_data 1.3.0
lazy_loader 0.4
libmambapy 1.5.9
locket 1.0.0
loguru 0.7.3
lxml 5.3.1
lz4 4.3.3
Mako 1.3.5
mamba 1.5.9
mapclassify 2.8.1
marisa-trie 1.2.1
Markdown 3.6
markdown-it-py 3.0.0
MarkupSafe 3.0.2
marshmallow 3.26.1
matplotlib 3.10.1
matplotlib-inline 0.1.7
mdurl 0.1.2
menuinst 2.1.2
mercantile 1.2.1
mizani 0.11.4
mlflow 2.16.2
mlflow-skinny 2.16.2
msgpack 1.1.0
multidict 6.1.0
multivolumefile 0.2.3
munkres 1.1.4
murmurhash 1.0.12
mypy-extensions 1.0.0
narwhals 1.30.0
nbclient 0.10.0
nbformat 5.10.4
nest_asyncio 1.6.0
networkx 3.4.2
nltk 3.9.1
numpy 2.2.3
opencv-python-headless 4.10.0.84
openpyxl 3.1.5
opentelemetry-api 1.16.0
opentelemetry-sdk 1.16.0
opentelemetry-semantic-conventions 0.37b0
orjson 3.10.15
outcome 1.3.0.post0
OWSLib 0.28.1
packaging 24.2
pandas 2.2.3
paramiko 3.5.0
parso 0.8.4
partd 1.4.2
pathspec 0.12.1
patsy 1.0.1
Pebble 5.1.0
pexpect 4.9.0
pickleshare 0.7.5
pillow 11.1.0
pip 24.2
platformdirs 4.3.6
plotly 5.24.1
plotnine 0.13.6
pluggy 1.5.0
polars 1.8.2
preshed 3.0.9
prometheus_client 0.21.0
prometheus_flask_exporter 0.23.1
prompt_toolkit 3.0.48
propcache 0.3.0
protobuf 4.25.3
psutil 7.0.0
ptyprocess 0.7.0
pure_eval 0.2.3
py7zr 0.20.8
pyarrow 17.0.0
pyarrow-hotfix 0.6
pyasn1 0.6.1
pyasn1_modules 0.4.1
pybcj 1.0.3
pycosat 0.6.6
pycparser 2.22
pycryptodomex 3.21.0
pydantic 2.10.6
pydantic_core 2.27.2
pydantic-settings 2.8.1
Pygments 2.19.1
PyNaCl 1.5.0
pynsee 0.1.8
pyogrio 0.10.0
pyOpenSSL 24.2.1
pyparsing 3.2.1
pyppmd 1.1.1
pyproj 3.7.1
pyshp 2.3.1
PySocks 1.7.1
python-dateutil 2.9.0.post0
python-dotenv 1.0.1
python-magic 0.4.27
pytz 2025.1
pyu2f 0.1.5
pywaffle 1.1.1
PyYAML 6.0.2
pyzmq 26.3.0
pyzstd 0.16.2
querystring_parser 1.2.4
rasterio 1.4.3
referencing 0.36.2
regex 2024.9.11
requests 2.32.3
requests-cache 1.2.1
requests-toolbelt 1.0.0
retrying 1.3.4
rich 13.9.4
rpds-py 0.23.1
rsa 4.9
rtree 1.4.0
ruamel.yaml 0.18.6
ruamel.yaml.clib 0.2.8
s3fs 2023.12.2
s3transfer 0.11.3
scikit-image 0.24.0
scikit-learn 1.6.1
scipy 1.13.0
seaborn 0.13.2
selenium 4.29.0
setuptools 76.0.0
shapely 2.0.7
shellingham 1.5.4
six 1.17.0
smart-open 7.1.0
smmap 5.0.0
sniffio 1.3.1
sortedcontainers 2.4.0
soupsieve 2.5
spacy 3.8.4
spacy-legacy 3.0.12
spacy-loggers 1.0.5
SQLAlchemy 2.0.39
sqlparse 0.5.1
srsly 2.5.1
stack-data 0.6.2
statsmodels 0.14.4
tabulate 0.9.0
tblib 3.0.0
tenacity 9.0.0
texttable 1.7.0
thinc 8.3.4
threadpoolctl 3.6.0
tifffile 2025.3.13
toolz 1.0.0
topojson 1.9
tornado 6.4.2
tqdm 4.67.1
traitlets 5.14.3
trio 0.29.0
trio-websocket 0.12.2
truststore 0.9.2
typer 0.15.2
typing_extensions 4.12.2
typing-inspect 0.9.0
tzdata 2025.1
Unidecode 1.3.8
url-normalize 1.4.3
urllib3 1.26.20
uv 0.6.8
wasabi 1.1.3
wcwidth 0.2.13
weasel 0.4.1
webdriver-manager 4.0.2
websocket-client 1.8.0
Werkzeug 3.0.4
wheel 0.44.0
wordcloud 1.9.3
wrapt 1.17.2
wsproto 1.2.0
xgboost 2.1.1
xlrd 2.0.1
xyzservices 2025.1.0
yarl 1.18.3
yellowbrick 1.5
zict 3.0.0
zipp 3.21.0
zstandard 0.23.0

View file history

SHA Date Author Description
26226eea 2025-01-31 17:54:48 lgaliana Chapitre cartographie en anglais
cbe6459f 2024-11-12 07:24:15 lgaliana Revoir quelques abstracts
886389c4 2024-10-21 08:59:14 lgaliana rappel mercator folium
9cf2bde5 2024-10-18 15:49:47 lgaliana Reconstruction complète du chapitre de cartographie
d2422572 2024-08-22 18:51:51 Lino Galiana At this point, notebooks should now all be functional ! (#547)
06d003a1 2024-04-23 10:09:22 Lino Galiana Continue la restructuration des sous-parties (#492)
8c316d0a 2024-04-05 19:00:59 Lino Galiana Fix cartiflette deprecated snippets (#487)
ce33d5dc 2024-01-16 15:47:22 Lino Galiana Adapte les exemples de code de cartiflette (#482)
005d89b8 2023-12-20 17:23:04 Lino Galiana Finalise l’affichage des statistiques Git (#478)
3fba6124 2023-12-17 18:16:42 Lino Galiana Remove some badges from python (#476)
4cd44f35 2023-12-11 17:37:50 Antoine Palazzolo Relecture NLP (#474)
1f23de28 2023-12-01 17:25:36 Lino Galiana Stockage des images sur S3 (#466)
b68369d4 2023-11-18 18:21:13 Lino Galiana Reprise du chapitre sur la classification (#455)
09654c71 2023-11-14 15:16:44 Antoine Palazzolo Suggestions Git & Visualisation (#449)
889a71ba 2023-11-10 11:40:51 Antoine Palazzolo Modification TP 3 (#443)
ad654c5f 2023-10-10 14:23:05 linogaliana CQuick fix gzip csv
1c646606 2023-10-04 15:52:52 Lino Galiana Quick fix remove contextily (#420)
154f09e4 2023-09-26 14:59:11 Antoine Palazzolo Des typos corrigées par Antoine (#411)
c7f8c941 2023-09-01 09:27:43 Lino Galiana Ajoute un champ citation (#403)
17a238f2 2023-08-30 15:06:18 Lino Galiana Nouvelles données compteurs (#402)
0035b743 2023-08-29 14:51:26 Lino Galiana Temporary fix for cartography pipeline (#401)
a8f90c2f 2023-08-28 09:26:12 Lino Galiana Update featured paths (#396)
3bdf3b06 2023-08-25 11:23:02 Lino Galiana Simplification de la structure 🤓 (#393)
78ea2cbd 2023-07-20 20:27:31 Lino Galiana Change titles levels (#381)
8df7cb22 2023-07-20 17:16:03 linogaliana Change link
f0c583c0 2023-07-07 14:12:22 Lino Galiana Images viz (#371)
f21a24d3 2023-07-02 10:58:15 Lino Galiana Pipeline Quarto & Pages 🚀 (#365)
38693f62 2023-04-19 17:22:36 Lino Galiana Rebuild visualisation part (#357)
32486330 2023-02-18 13:11:52 Lino Galiana Shortcode rawhtml (#354)
b0abd027 2022-12-12 07:57:22 Lino Galiana Fix cartiflette in additional exercise (#334)
e56f6fd5 2022-12-03 17:00:55 Lino Galiana Corrige typos exo compteurs (#329)
f10815b5 2022-08-25 16:00:03 Lino Galiana Notebooks should now look more beautiful (#260)
494a85ae 2022-08-05 14:49:56 Lino Galiana Images featured ✨ (#252)
d201e3cd 2022-08-03 15:50:34 Lino Galiana Pimp la homepage ✨ (#249)
5698e303 2022-06-03 18:28:37 Lino Galiana Finalise widget (#232)
7b9f27be 2022-06-03 17:05:15 Lino Galiana Essaie régler les problèmes widgets JS (#231)
12965bac 2022-05-25 15:53:27 Lino Galiana :launch: Bascule vers quarto (#226)
9c71d6e7 2022-03-08 10:34:26 Lino Galiana Plus d’éléments sur S3 (#218)
66a52761 2021-11-23 16:13:20 Lino Galiana Relecture partie visualisation (#181)
2a8809fb 2021-10-27 12:05:34 Lino Galiana Simplification des hooks pour gagner en flexibilité et clarté (#166)
2f4d3905 2021-09-02 15:12:29 Lino Galiana Utilise un shortcode github (#131)
2e4d5862 2021-09-02 12:03:39 Lino Galiana Simplify badges generation (#130)
4cdb759c 2021-05-12 10:37:23 Lino Galiana :sparkles: :star2: Nouveau thème hugo :snake: :fire: (#105)
7f9f97bc 2021-04-30 21:44:04 Lino Galiana 🐳 + 🐍 New workflow (docker 🐳) and new dataset for modelization (2020 🇺🇸 elections) (#99)
29242152 2020-10-08 13:35:18 Lino Galiana modif slug cartographie
64776878 2020-10-08 13:31:00 Lino Galiana Visualisation cartographique (#68)
Back to top

References

Chen, Chun-houh, Wolfgang Härdle, Antony Unwin, and Michael Friendly. 2008. “A Brief History of Data Visualization.” Handbook of Data Visualization, 15–56.

Footnotes

  1. Stricto sensu, we should verify that these columns accurately correspond to the official population counts defined by Insee. This variable is natively provided by IGN in its basemap data. We leave this verification to interested readers, as it offers a good opportunity to practice Pandas skills.↩︎

  2. Lambert 93 provides area in square meters. To convert it to km², use div(1e6).↩︎

Citation

BibTeX citation:
@book{galiana2023,
  author = {Galiana, Lino},
  title = {Python Pour La Data Science},
  date = {2023},
  url = {https://pythonds.linogaliana.fr/},
  doi = {10.5281/zenodo.8229676},
  langid = {en}
}
For attribution, please cite this work as:
Galiana, Lino. 2023. Python Pour La Data Science. https://doi.org/10.5281/zenodo.8229676.