Files
training.python.datascience/documentation/new-02.1-eda-matplotlib.md
2025-07-04 19:58:11 +02:00

209 lines
7.3 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
title: Matplotlib
author: Steve Kossouho
---
# Rendu de graphiques Matplotlib
----
## Qu'est-ce que Matplotlib ?
Matplotlib, selon ses créateurs (John D. Hunter et al.), est une bibliothèque complète,
pour créer des graphiques statiques, animés ou interactifs 👀.
La bibliothèque rend des choses simples très simples,
et des choses compliquées possibles
(_et accessoirement beaucoup de choses simples compliquées_).
----
## Comment fonctionne Matplotlib ?
La bibliothèque permet de dessiner des graphiques, souvent très simplement en
assemblant des éléments, par exemple un axe avec une certaine échelle, et
une ligne suivant la même échelle.
Les possibilités sont très nombreuses, et les concepts proposés aussi, avec une
approche très différente de ce qui se fait normalement en Python; usage de variables
globales ou classes complexes pour représenter de simples dégradés de couleurs.
----
## Graphiques avec Pandas
----
La bibliothèque Matplotlib permet facilement de générer et afficher
des graphiques, mais les objets `DataFrame`{.python} proposent un
raccourci pour les générer facilement.
Chaque objet possède une méthode générale `.plot()`{.python}, qui possède
des attributs qui sont des méthodes spécifiques pour chaque type
de graphique.
----
| Méthode | Explication succincte |
|----------------------|----------------------------------------------|
| [`plot.area`][1] | Tracer un graphique en _aires empilées_ |
| [`plot.bar`][2] | Tracer un graphique en _barres verticales_ |
| [`plot.barh`][3] | Tracer un graphique en _barres horizontales_ |
| [`plot.box`][4] | Tracer un graphique à _moustaches_ (boxplot) |
| [`plot.density`][5] | Tracer une estimation de densité de noyau |
| [`plot.hexbin`][6] | Tracer un graphique hexagonal en 2D |
| [`plot.hist`][7] | Tracer un _histogramme_ |
| [`plot.kde`][8] | Tracer une estimation de densité de noyau |
| [`plot.line`][9] | Tracer un graphique en _lignes_ |
| [`plot.pie`][10] | Tracer un graphique en _secteurs_ |
| [`plot.scatter`][11] | Tracer un _nuage de points_ (scatter plot) |
[1]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.area.html
[2]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.bar.html
[3]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.barh.html
[4]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.box.html
[5]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.density.html
[6]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.hexbin.html
[7]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.hist.html
[8]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.kde.html
[9]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.line.html
[10]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.pie.html
[11]: https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.scatter.html
----
### Barres
```python {.numberLines}
import pandas as pd
from matplotlib import use, pyplot
# Utiliser tkinter
use("TkAgg")
# Données à afficher
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49]
})
# Générer un graphique dans Matplotlib
axis = data.plot.bar(x="product", y="price")
# Afficher le dernier graphique généré
pyplot.show()
```
[`DataFrame.plot.bar`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.bar.html#pandas.DataFrame.plot.bar)
----
![Rendu de base du graphique en barres](assets/images/eda-matplotlib-bar-default.png)
Notez que les étiquettes des barres, entre autres, débordent de l'image. D'autres défauts généraux
sont habituellement rencontrés avec Matplotlib, comme l'absence d'affichage de valeur pour les
éléments des graphiques, ou l'absence de gestion du contraste lorsqu'il faut afficher du texte sur
des fonds sombres ou clairs.
----
### Personnalisation
De nombreuses options de personnalisation permettent de changer le rendu par défaut des graphiques.
La variable `rcParams`{.python} de `pyplot`{.python} est un dictionnaire proposant des options
pour changer entre autres la police de texte par défaut ou les styles de ligne.
```python {.numberLines}
import matplotlib
import pandas as pd
from matplotlib import pyplot
matplotlib.use("TkAgg")
pyplot.style.use('ggplot')
pyplot.rcParams["font.family"] = "Cabin"
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49],
"wpu": [200, 180, 140, 200]
})
# Générer un graphique dans Matplotlib
data.plot.bar(x="product", y=["price", "wpu"], rot=0.0, secondary_y="wpu", legend="reverse")
pyplot.gcf().savefig("test.png")
```
[Options de `rcParams`](https://matplotlib.org/stable/api/matplotlib_configuration_api.html#matplotlib.rcParams)
----
![Rendu personnalisé du graphique en barres](assets/images/eda-matplotlib-bar-themed.png)
----
#### Ajout d'étiquettes sur des barres
```python {.numberLines}
import matplotlib
import pandas as pd
from matplotlib import pyplot
from matplotlib.axes import Axes
matplotlib.use("TkAgg")
pyplot.style.use('ggplot')
pyplot.rcParams["font.family"] = "Cabin"
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49],
"wpu": [200, 180, 140, 200]
})
# Générer un graphique dans Matplotlib
data.plot.bar(x="product", y=["price", "wpu"], rot=0.0, secondary_y="wpu", legend="reverse", title="Prix et poids unitaires")
prices, weights = pyplot.gcf().axes # type: Axes
prices.legend(bbox_to_anchor=(0.0, 1.1), loc="upper left")
weights.legend(bbox_to_anchor=(1.0, 1.1), loc="upper right")
# Il est difficile de personnaliser le contenu du graphique
options: dict = {"fontsize": 8, "color": "w", "rotation": 90, "label_type": "center"}
prices.bar_label(prices.containers[0], labels=[f"{p}€" for p in data["price"]], **options)
weights.bar_label(weights.containers[0], labels=[f"{p}g" for p in data["wpu"]], **options)
pyplot.gcf().savefig("bar-labeled.png")
```
----
![Rendu personnalisé du graphique en barres](assets/images/eda-matplotlib-bar-labeled.png)
Le travail nécessaire est peut-être trop élevé pour une visualisation simple.
----
### Secteurs (camembert)
```python {.numberLines}
import pandas as pd
from matplotlib import use, pyplot
# Utiliser tkinter
use("TkAgg")
pyplot.style.use('ggplot')
pyplot.rcParams["font.family"] = "Cabin"
# Données à afficher
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49]
})
# Générer un graphique dans Matplotlib
axis = data.set_index("product").plot.pie(y="price", title="Prix")
# Afficher le dernier graphique généré
pyplot.show()
```
[`DataFrame.plot.pie`](https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.plot.pie.html#pandas.DataFrame.plot.pie)
----
![Rendu personnalisé du graphique en secteurs](assets/images/eda-matplotlib-pie-themed.png)