Files
training.python.datascience/documentation/02.2-eda-plotly.md
Steve Kossouho d06fd5414d Rename documentation files
Removed new- prefix.
Added old- prefix to old files.
2025-07-12 17:03:38 +02:00

335 lines
11 KiB
Markdown
Raw Permalink 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: Plotly Express
author: Steve Kossouho
---
# Rendu de graphiques avec Plotly
----
## Qu'est-ce que Plotly ?
Selon le site de Plotly : La bibliothèque graphique Python Plotly crée des graphiques interactifs de qualité
propre à la publication.
![Logo de Plotly](assets/images/eda-plotly-logo.png)
----
## Comment fonctionne Plotly ?
Plotly est une bibliothèque Python compatible avec les `DataFrame`{.python} Pandas, qui permet de créer des graphiques
interactifs, et cela grâce aux technologies web (HTML, CSS et JS). Un navigateur suffit à
afficher le contenu d'un graphique généré avec Plotly.
La bibliothèque est relativement facile à prendre en main et bien documentée, de sorte
qu'il est simple de faire des choses simples, et abordable de produire des choses plus
complexes.
[Documentation de Plotly pour Python](https://plotly.com/python/)
----
## Plotly Express
Plotly express est une bibliothèque de Plotly proposant très simplement de
créer des graphiques, depuis des `DataFrame`{.python} Pandas. Elle propose
toute la variété de graphiques générables avec Plotly, via des fonctions prêtes
à l'emploi prenant en argument un `DataFrame`{.python}.
----
### Installer Plotly Express
```bash= {.numberLines}
pip install plotly
```
----
### Barres
Générer un graphique en barres est assez simple avec Plotly, et fonctionne
de manière relativement satisfaisante par défaut (ex. texte en blanc sur fond sombre)
```python {.numberLines}
import pandas as pd
from plotly import express
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
figure = express.bar(data, x="product", y=["price", "wpu"], barmode="group", title="Prix et poids unitaires")
figure.show()
```
[Documentation de `bar`](https://plotly.com/python-api-reference/generated/plotly.express.bar.html)
----
![Rendu de base en barres](assets/images/eda-plotly-express-bar-default.png)
----
### Barres (sur un objet `Series`)
Vous pouvez également générer un graphique en partant d'un objet de type `Series`, même si l'objet ne contient
en lui-même qu'une seule colonne. Les valeurs d'index peuvent également servir sur un axe; il suffit d'utiliser
la valeur `None`{.python} :
```python {.numberLines}
import pandas as pd
from plotly import express
values = pd.Series(
data=[1.99, 2.49, 2.99, 3.49],
index=["pomme", "poire", "banane", "peche"],
name="price"
)
# Générer un graphique
figure = express.bar(values, x=None, y="price")
figure.show()
```
L'axe des Y pourra utiliser le nom associé à l'objet `Series` (`values.name`{.python})
----
Quelques personnalisations sont possibles, notamment via la notion de `template` (thème),
et de `layout` (organisation du contenu).
```python {.numberLines}
import pandas as pd
from plotly import express
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. Plotly express ne prend en charge qu'un seul graphique par figure
figure = express.bar(data, x="product", y="price", title="Prix", template="seaborn",
labels={"price": "Prix", "product": "Produit"})
figure.layout.update({"font": {"family": "Cabin", "size": 13}})
figure.show()
```
----
Voici une liste des valeurs possibles fournies par Plotly pour l'argument `template`{.python}:
- `ggplot2` : Thème par défaut de GGPlot2 pour [R]{.naming}
- `seaborn` : Thème par défaut de Seaborn pour Python
- `plotly` : Thème par défaut de Plotly
- `plotly_white`
- `plotly_dark`
- `presentation`
- `xgridoff`
- `ygridoff`
- `gridon`
- `none`
----
![Rendu personnalisé en barres](assets/images/eda-plotly-express-bar-themed.png)
----
![Rendu personnalisé en barres 2](assets/images/eda-plotly-express-bar-custom.png)
----
### Secteurs concentriques
Le graphique [sunburst]{.naming} permet d'afficher des secteurs, et de les découper en sous-catégories
dans des anneaux concentriques. Ici, nous avons un `DataFrame`{.python} avec des ventes par ville,
chaque ville appartenant à un pays.
```python {.numberLines}
import pandas as pd
import plotly
from plotly.express import sunburst
if __name__ == '__main__':
df = pd.DataFrame(data={
"country": ["France", "France", "Spain", "Spain", "England", "England", "England"],
"city": ["Montpellier", "Bordeaux", "Madrid", "Valencia", "London", "Manchester", "Bristol"],
"sales": [150_000, 127_000, 97_200, 137_250, 200_000, 180_000, 150_000]
})
plot = sunburst(df, path=["country", "city"], values="sales", title="Sales by country and city", template="ggplot2",
color_discrete_sequence=plotly.colors.qualitative.Dark2)
plot.layout.update({"font": {"family": "Cabin", "size": 13}})
plot.show()
```
[Documentation de `sunburst`](https://plotly.com/python-api-reference/generated/plotly.express.sunburst.html)
----
![Rendu personnalisé en [sunburst]{.naming}](assets/images/eda-plotly-express-sunburst-themed.png)
----
### Nuages de points
Les nuages de points ([scatter plot]{.naming}) sont un moyen pratique de mettre en regard deux valeurs
d'une même observation afin d'essayer de déduire une tendance ou une corrélation. Ils se présentent en
2 dimensions, mais deux autres axes peuvent être représentés via la taille ou la couleur des points du
graphique.
```python {.numberLines}
import pandas as pd
from plotly import express as px
data = pd.read_csv("https://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data", header=None,
names=["sepal-length", "sepal-width", "petal-length", "petal-width", "class"])
plot = px.scatter(data, x="sepal-length", y="sepal-width", size="petal-width", color="class", template="seaborn",
title="Iris flowers dataset",
labels={"sepal-length": "Sepal length", "sepal-width": "Sepal width", "petal-width": "Petal width", "class": "Class"})
plot.layout.update({"font": {"family": "Cabin", "size": 13}})
plot.show()
```
[Documentation de `scatter`](https://plotly.com/python-api-reference/generated/plotly.express.scatter.html)
----
![Rendu personnalisé en [scatter]{.naming}](assets/images/eda-plotly-express-scatter-themed.png)
----
## Construction
Cette section regroupe plusieurs solutions pour parvenir à certains résultats.
----
### Deux axes Y dans un graphique en barres
Par défaut, Plotly Express ne génère pas deux axes distincts lorsque vous affichez un graphique
avec deux colonnes pour l'axe Y. Si leurs ordres de grandeur sont différents, les barres partageront toutefois
la même échelle.
Pour obtenir deux axes distincts en Y, nous devons utiliser Plotly manuellement. Rien d'anormalement
complexe toutefois :
```python {.numberLines}
import pandas as pd
from plotly.graph_objs import Figure, Bar
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49], "wpu": [200, 180, 140, 200]
})
figure = Figure([
Bar(name="Prix", x=data["product"], y=data["price"], yaxis="y", offsetgroup=1),
Bar(name="Poids", x=data["product"], y=data["wpu"], yaxis="y2", offsetgroup=2),
])
# Afficher le dernier graphique généré
figure.layout.update({
"template": "seaborn",
"title": "Prix et poids unitaires", "font": {"family": "Cabin", "size": 13},
"yaxis": {"title": "Prix (€)"}, "yaxis2": {"title": "Poids (g)", "overlaying": "y", "side": "right"}
})
figure.show()
```
----
![Rendu avec deux axes Y](assets/images/eda-plotly-compose-2axes.png)
----
### Texte personnalisé dans un camembert
Par défaut, les secteurs de graphique camembert ([pie]{.naming}) affichent la taille
d'un secteur en pourcents du total. Vous pouvez y formater d'autres infos :
```python {.numberLines}
import pandas as pd
from plotly import express as px
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49], "wpu": [200, 180, 140, 200]
})
figure = px.pie(data, values="price", names="product", title="Prix")
# Afficher le dernier graphique généré
figure.layout.update({
"template": "seaborn",
"title": "Prix au kilo", "font": {"family": "Cabin", "size": 13},
})
figure.update_traces(**{"textinfo": "label+value", "texttemplate": "%{label}<br>%{value:.2f}€"})
figure.show()
```
[Personnalisation des camemberts](https://plotly.com/python/pie-charts/)
----
![Rendu avec deux lignes de texte par secteur](assets/images/eda-plotly-compose-pie-label.png)
----
### Choix de couleurs
Vous pouvez définir votre propre choix de couleurs pour certains graphiques, avec certains arguments. L'argument
`color_discrete_sequence`{.python} permet de définir une liste de couleurs à appliquer en tourniquet
aux éléments du dessin.
```python {.numberLines}
import pandas as pd
from plotly import express as px
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49], "wpu": [200, 180, 140, 200]
})
figure = px.pie(data, values="price", names="product", title="Prix", color_discrete_sequence=["red", "orange", "yellow", "#8F0"])
figure.layout.update({"template": "seaborn", "title": "Prix au kilo", "font": {"family": "Cabin", "size": 13}})
figure.show()
```
Plotly Express fournit des séquences ou dégradés de couleurs, dont la référence est disponible ci-dessous :
[Couleurs et séquences de couleurs](https://plotly.com/python/discrete-color/)
----
![Rendu avec choix de couleurs par secteur](assets/images/eda-plotly-express-pie-colors.png)
----
### Couleur dépendante de la valeur
Vous pouvez sur certains graphiques définir un gradient à appliquer aux éléments du dessin
selon une valeur qui leur est associée. Ici, nous avons un graphique en barres, où la couleur
de chaque barre dépend de la valeur de la colonne `price`.
```python {.numberLines}
import pandas as pd
from plotly import express as px
data = pd.DataFrame(data={
"product": ["pomme", "poire", "banane", "pêche"],
"price": [1.99, 2.49, 2.99, 3.49], "wpu": [200, 180, 140, 200]
})
figure = px.bar(data, y="price", x="product", title="Prix", color="price", color_continuous_scale=["red", "orange", "yellow", "#8F0"])
figure.layout.update({"template": "seaborn", "title": "Prix au kilo", "font": {"family": "Cabin", "size": 13}})
figure.show()
```
Ici, l'argument `color` permet d'indiquer sur les valeurs de quelle colonne colorier les barres.
L'argument `color_continuous_scale` permet de définir les couleurs d'un dégradé à utiliser pour
colorier les barres.
----
![Rendu avec gradient de couleurs](assets/images/eda-plotly-express-bar-gradient.png)