--- 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)