Cours Python · Module 8: Data science

Visualisation - voir ce qu'un tableau ne montre pas

20 min de lecture
Dans cette leçon14

Tu as devant toi six mois d'observations de la réserve : 8, 12, 15, 10, 18, 22. Chaque nombre est juste, chaque nombre est daté, tous tiennent dans une seule colonne de DataFrame. Et alors ? Est-ce que la population de lions augmente ? Est-ce que le mois de mai est une exception ou le début d'une tendance ? Avec six valeurs, tu arrives encore à trancher de tête. Avec trois mille lignes, tu ne tranches plus rien du tout, et c'est exactement ce qu'on ramène d'une seule saison sur le terrain.

Ma première saison dans la réserve s'est terminée sur un carnet plein de relevés dont il ne ressortait rien. C'est seulement le jour où j'ai planté des épingles sur une carte et où je les ai reliées avec de la ficelle que j'ai vu ce que le carnet m'avait caché pendant quatre mois : le troupeau suivait la pluie. Un graphique, c'est cette même carte à épingles - les mêmes données, disposées pour que le regard attrape le motif avant que la tête ait eu le temps de calculer quoi que ce soit.

Cette leçon te met deux outils entre les mains. Matplotlib est l'atelier : tu y montes ton graphique pièce par pièce, la courbe, le nom des axes, le titre, la légende. Seaborn est l'étage bâti au-dessus de Matplotlib : il connaît déjà les graphiques statistiques classiques et les dessine en une seule instruction. On commence par l'atelier, parce que Seaborn s'appuie dessus de tout son poids.

D'où vient plt

Matplotlib est un paquet, c'est-à-dire un gros ensemble de modules. Le dessin y est confié à un module bien précis : pyplot. Ce n'est pas une bibliothèque séparée, il vit à l'intérieur du paquet matplotlib, et il faut donc descendre jusqu'à lui par un chemin à points : matplotlib.pyplot. Écrire ça à chaque ligne serait un supplice, alors l'usage veut qu'on lui donne le raccourci plt avec le mot-clé as. Ce n'est pas une règle du langage, seulement une convention, mais une convention si solide que chaque exemple de la documentation et chaque réponse trouvée en ligne supposent plt.

Trois écritures tournent autour de cette ligne unique sans jamais fonctionner, et mieux vaut les connaître que d'y perdre une soirée. import pyplot as plt part à la recherche d'un paquet indépendant appelé pyplot : il n'existe pas, Python s'arrête sur ModuleNotFoundError: No module named 'pyplot'. from matplotlib import plot va chercher le nom plot, mais le module s'appelle pyplot et pas plot, alors tu récoltes ImportError: cannot import name 'plot' from 'matplotlib'. Le plus sournois est import matplotlib as plt : cette ligne passe sans broncher, parce que le paquet matplotlib existe pour de bon. C'est le premier appel qui se casse la figure, sur AttributeError: module 'matplotlib' has no attribute 'plot', puisque les fonctions de dessin habitent le module pyplot et pas la racine du paquet.

1import matplotlib.pyplot as plt

Après cette ligne, aucune fenêtre ne s'ouvre et aucun fichier n'apparaît. L'import se contente de charger le module en mémoire et d'y accrocher l'étiquette plt. Le dessin ne commencera qu'à l'instruction suivante, donc cette ligne-là ne casse jamais rien, et c'est la seule des quatre écritures qui soit correcte.

Première piste : la courbe des observations

Commençons par la question la plus simple qu'on pose aux données d'une réserve : comment le nombre d'observations évolue-t-il dans le temps ? Pour une évolution dans le temps, on prend une courbe, parce que le trait qui relie les points montre une direction et pas seulement des valeurs. C'est la fonction plot qui la trace : elle reçoit deux listes, la première atterrit sur l'axe horizontal, la seconde sur l'axe vertical. À la fin on appelle show, l'instruction qui veut dire "montre-moi ce que tu viens de dessiner".

1months = ["Jan", "Fev", "Mar", "Avr", "Mai", "Juin"]
2lion_sightings = [8, 12, 15, 10, 18, 22]
3
4plt.plot(months, lion_sightings)
5plt.show()

Les six nombres du carnet sont devenus une courbe qui grimpe franchement, avec un seul creux en avril. Retiens le partage des rôles : plot dessine en mémoire, show affiche. Ce sont deux gestes distincts, et oublier show dans un script ordinaire donne un programme qui s'exécute, se termine sans erreur et ne montre rien du tout. show de son côté ne calcule rien et ne modifie aucune donnée : la liste lion_sightings est exactement la même après l'appel qu'avant. Apprends-la caractère par caractère, tu vas l'écrire des centaines de fois : plt, ., show, (, ).

Un graphique sans étiquettes, ce sont des épingles sans carte

Le graphique précédent a un défaut : personne d'autre que toi ne sait ce qu'il représente. Les axes n'ont pas de nom, il n'y a pas de titre, et si tu ajoutes une deuxième espèce, plus moyen de distinguer les courbes. Quatre fonctions aux noms transparents réparent tout ça : title pose le titre, xlabel nomme l'axe horizontal, ylabel l'axe vertical, et legend construit la légende à partir des étiquettes passées à plot dans le paramètre label. S'y ajoutent figure avec son paramètre figsize, qui donne la taille de la feuille en pouces sous la forme d'un couple de nombres, et grid, qui pose un quadrillage de repère.

1elephant_sightings = [5, 7, 6, 9, 11, 8]
2
3plt.figure(figsize=(10, 6))
4plt.plot(months, lion_sightings, marker="o", label="Lions", color="gold")
5plt.plot(months, elephant_sightings, marker="s", label="Elephants", color="gray")
6
7plt.title("Observations dans la reserve - premier semestre")
8plt.xlabel("Mois")
9plt.ylabel("Nombre d'observations")
10plt.legend()
11plt.grid(True, alpha=0.3)
12plt.show()

Deux appels à plot à la suite ne font pas deux graphiques, ils posent deux courbes sur la même figure. Une feuille neuve n'apparaît qu'avec plt.figure(...), et c'est pour cette raison que je te recommande de commencer chaque graphique par cette ligne : sans elle, le deuxième graphique d'un script vient se dessiner par-dessus le premier et tu obtiens de la bouillie. Le paramètre marker marque chaque mesure d'un rond ou d'un carré, color fixe la couleur, et alpha règle la transparence sur une échelle de 0 à 1. Toutes ces fonctions ne touchent qu'à l'apparence du dessin. Les nombres des listes restent intacts, et la courbe des lions passe exactement là où elle passait avant qu'on lui ajoute un titre et une légende.

Enregistrer dans un fichier : savefig avant show

Un graphique regardé à l'écran disparaît avec la fenêtre qu'on referme. Pour le rapport d'expédition il te faut un fichier, et c'est le travail de savefig : tu lui donnes un nom de fichier, elle écrit le dessin sur le disque. L'extension du nom décide du format, et le paramètre dpi décide de la résolution, plus il est haut, plus l'image est nette et plus le fichier est lourd.

1plt.figure(figsize=(10, 6))
2plt.plot(months, lion_sightings, marker="o", label="Lions")
3plt.legend()
4
5plt.savefig("observations.png", dpi=150)
6plt.show()

L'ordre des deux dernières lignes n'a rien d'anodin, c'est même le piège numéro un de cette leçon : savefig doit passer avant show. Une fois la fenêtre d'aperçu refermée, certains backends font le ménage et vident la figure ; un savefig appelé après enregistre alors une image blanche, sans erreur et sans le moindre avertissement, simplement vide. L'enregistrement, lui, ne ferme pas la fenêtre et ne te dispense pas d'appeler show si tu veux encore regarder ton graphique.

Les barres : plt.bar, jamais plt.bars

La courbe est parfaite pour le temps, beaucoup moins pour les comparaisons. Quand tu as quatre espèces et leurs effectifs, tu veux voir quelle barre est la plus haute, pas relier le lion à la girafe par un trait, puisqu'il n'existe aucun "entre les deux". Pour comparer des catégories on prend un diagramme en barres, et c'est une fonction au nom court et sans ambiguïté qui le trace : bar. Son premier argument est la liste des noms de catégories, le second la liste des valeurs ; le color facultatif accepte une seule couleur ou une liste de couleurs, une par barre.

Ce nom, il faut le retenir à la lettre, parce que Matplotlib ne pardonne pas la créativité. La fonction s'appelle bar, au singulier, et pas bars. Il n'existe pas non plus de fonction column : dans Matplotlib les colonnes s'appellent des barres, un point c'est tout. Et il n'existe pas davantage de fonction histogram ; le graphique de distribution se trace avec hist, on y vient dans un instant, tandis que np.histogram de NumPy est une tout autre affaire puisqu'elle renvoie des nombres au lieu d'un dessin. Ces trois confusions se terminent toutes sur le même message : AttributeError: module 'matplotlib.pyplot' has no attribute ....

1species = ["Lion", "Elephant", "Cheetah", "Giraffe"]
2populations = [120, 450, 85, 200]
3
4plt.figure(figsize=(10, 6))
5plt.bar(species, populations, color=["gold", "gray", "orange", "brown"])
6plt.title("Populations des especes de la reserve")
7plt.xlabel("Espece")
8plt.ylabel("Population")
9plt.show()

Quatre barres, un seul regard, et tu sais que les éléphants sont plus de cinq fois plus nombreux que les guépards. L'ordre des barres vient directement de l'ordre de la liste species : bar ne trie rien et n'additionne rien à ta place, elle pose simplement côte à côte autant de rectangles que tu lui as donné de valeurs. Si tu veux des barres horizontales, il existe une fonction dédiée, barh, mais avec des noms d'espèces les barres verticales se lisent mieux et ce sont elles que je te recommande.

L'histogramme n'est pas un diagramme en barres

Admettons que tu aies pesé vingt-quatre lions au cours de la saison. Un diagramme en barres te donnerait ici vingt-quatre barres, une par animal, illisible et parfaitement inutile. La question n'est d'ailleurs pas celle-là : ce que tu veux savoir, c'est quels poids sont courants et lesquels sont rares. C'est le rôle de l'histogramme, qui découpe l'étendue des valeurs en intervalles, appelés classes ou paniers, et montre combien de mesures sont tombées dans chacun. La fonction qui le trace est hist ; son paramètre bins fixe le nombre de classes et edgecolor dessine un liseré pour que les barres voisines ne se confondent pas.

1lion_weights = [168, 175, 190, 182, 177, 195, 160, 188,
2                172, 181, 199, 165, 178, 186, 173, 191,
3                169, 184, 176, 193, 180, 187, 171, 179]
4
5plt.figure(figsize=(10, 6))
6plt.hist(lion_weights, bins=6, edgecolor="black", alpha=0.7)
7plt.title("Distribution du poids des lions")
8plt.xlabel("Poids [kg]")
9plt.ylabel("Nombre d'individus")
10plt.show()

La différence avec bar est de fond, même si les deux graphiques affichent des barres. À bar tu passes deux listes, les catégories et les valeurs déjà calculées. À hist tu passes une seule liste de mesures brutes, et c'est la fonction qui fait le comptage à ta place. L'axe vertical d'un histogramme montre toujours un effectif, même si tu ne l'écris nulle part. Changer bins ne change que la façon de découper l'étendue, les données elles-mêmes ne bougent pas : avec trop peu de classes la distribution paraît lisse, avec trop de classes elle se désagrège en mesures isolées.

Les parts du tout : plt.pie

Parfois le nombre absolu d'animaux ne t'intéresse pas ; ce que tu veux savoir, c'est quelle fraction de la réserve représente chaque espèce. À la question "combien de pour cent" répond le diagramme circulaire, le camembert, tracé par la fonction pie. Tu lui donnes la liste des valeurs, la liste des étiquettes dans le paramètre labels, et un motif de formatage des pourcentages dans autopct : l'écriture "%1.1f%%" signifie "une décimale, suivie du signe pour cent".

1plt.figure(figsize=(8, 8))
2plt.pie(populations, labels=species, autopct="%1.1f%%",
3        colors=["gold", "gray", "orange", "brown"])
4plt.title("Part de chaque espece dans la population")
5plt.show()

Les pourcentages inscrits sur les parts, c'est Matplotlib qui les a calculés tout seul en divisant chaque valeur par la somme de toutes les valeurs ; la liste populations contient toujours des effectifs bruts, pas des pourcentages. C'est aussi pour cela qu'un camembert n'a de sens que si tes valeurs forment vraiment un tout. Pour quatre espèces d'une même réserve, c'est le cas ; pour quatre mesures indépendantes, ça ne l'est plus, et au-delà d'une dizaine de catégories les parts deviennent si fines qu'il vaut mieux revenir à bar.

Deux nombres à la fois : plt.scatter

Jusqu'ici chaque graphique associait une catégorie et un nombre. Et si tu voulais vérifier que deux nombres avancent ensemble, par exemple que les mois les plus pluvieux sont aussi ceux où l'on croise le plus de lions ? C'est le travail du nuage de points, tracé par la fonction scatter, qui pose un point par couple de valeurs. Le paramètre s règle la taille des points et le alpha que tu connais déjà leur transparence, ce qui laisse voir les endroits où les points se superposent.

1rainfall_mm = [12, 18, 45, 80, 130, 165]
2
3plt.figure(figsize=(10, 6))
4plt.scatter(rainfall_mm, lion_sightings, s=100, alpha=0.7, color="gold")
5plt.title("Pluie et nombre d'observations")
6plt.xlabel("Precipitations [mm]")
7plt.ylabel("Observations de lions")
8plt.show()

Les six points s'alignent grossièrement le long d'une montée : plus il pleut, plus on observe. C'est une première piste et non une preuve, car scatter ne calcule rien et n'ajuste aucune droite, elle pose les points là où tu lui dis de les poser. L'ordre des arguments compte : la première liste part sur l'axe horizontal, la seconde sur l'axe vertical, et les intervertir donne un graphique tout aussi valide mais qui raconte une autre histoire.

Seaborn : une surcouche, pas un remplaçant

Matplotlib dessine tout, mais chaque graphique statistique, tu dois l'assembler toi-même. Seaborn va un cran plus loin : il connaît les graphiques courants de l'analyse de données, accepte directement un DataFrame Pandas et choisit tout seul les couleurs ainsi que les noms des axes à partir des noms de colonnes. Il ne remplace pas Matplotlib, il l'emballe, et c'est pourquoi plt.title et plt.show fonctionnent sur un graphique Seaborn exactement comme sur les tiens. La bibliothèque s'importe sous le raccourci sns, et la fonction set_style fixe un style commun à tous les dessins qui suivront.

Pour montrer la distribution des poids espèce par espèce, il nous faut les données au format long : une colonne avec le nom de l'espèce, une colonne avec la mesure, et une ligne par animal.

1import seaborn as sns
2import pandas as pd
3
4sns.set_style("whitegrid")
5
6observations = pd.DataFrame({
7    "species": ["Lion"] * 6 + ["Cheetah"] * 6 + ["Giraffe"] * 6,
8    "weight_kg": [168, 175, 190, 182, 177, 195,
9                  52, 58, 47, 61, 55, 49,
10                  810, 950, 880, 1020, 905, 870]
11})
12
13print(observations.shape)  # (18, 2)

Dix-huit lignes et deux colonnes, exactement le DataFrame de la leçon précédente : Seaborn n'introduit aucune structure de données à lui, il lit celle que tu connais déjà. L'appel à set_style n'a rien dessiné, il a seulement changé l'allure par défaut des graphiques encore à venir. Les dessins déjà produits restent tels quels.

Boxplot : la boîte, les moustaches et les valeurs aberrantes

L'histogramme a montré la distribution d'un seul groupe. Comment comparer maintenant les distributions de trois espèces côte à côte, sans tracer trois histogrammes séparés ? C'est le rôle de la boîte à moustaches, le boxplot, tracé par la fonction boxplot. Il résume une distribution en cinq nombres : le bord bas et le bord haut de la boîte, c'est-à-dire les quartiles qui découpent les données en quatre parts égales, le trait de la médiane au milieu de la boîte, et les moustaches qui s'étirent jusqu'aux valeurs encore ordinaires. Les points qui tombent au-delà des moustaches sont dessinés à part : ce sont les valeurs aberrantes, les outliers.

1plt.figure(figsize=(10, 6))
2sns.boxplot(data=observations, x="species", y="weight_kg")
3plt.title("Distribution du poids par espece")
4plt.show()

Trois boîtes sur un seul dessin, et on voit tout de suite que les guépards tiennent dans une plage étroite alors que les girafes font exploser l'échelle. Pour les lions, le quartile bas tombe à 175,5 kg, la médiane à 179,5 kg et le quartile haut à 188 kg ; ces trois nombres sont précisément les deux bords et le trait de la boîte. L'argument data reçoit le DataFrame entier, tandis que x et y sont des noms de colonnes et non les données elles-mêmes, et Seaborn tire les libellés des axes de ces noms tout seul.

Autant écarter tout de suite trois malentendus, parce que le mot "boîte" égare. Un boxplot ne sert pas à dessiner des cadres autour du texte : pour encadrer une annotation, il y a le paramètre bbox des fonctions de texte. Ce n'est pas non plus un outil pour dessiner des rectangles ; il en trace un, certes, mais ce rectangle est le graphique de cinq statistiques calculées, pas une forme dont tu fixerais les dimensions. Et il ne combine pas plusieurs graphiques dans des cadres : pour poser plusieurs graphiques sur une même page, c'est plt.subplots, que tu verras à la fin de la leçon. Un boxplot a exactement une mission, montrer la distribution des données avec ses quartiles et ses valeurs aberrantes. Ses proches parents sont sns.violinplot, qui remplace la boîte par la silhouette de la distribution, et sns.countplot, qui compte les lignes de chaque catégorie et en fait lui-même des barres.

La matrice de corrélation : les nombres avant l'image

Le nuage de points a montré le lien entre la pluie et les observations de lions, mais avec trois ou trente colonnes tu ne vas pas dessiner chaque paire séparément. Pandas sait calculer tous les liens d'un coup avec la méthode corr, qui renvoie une matrice de corrélation : un tableau où chaque case contient la force du lien entre deux colonnes, sur une échelle allant de moins un à un. Un veut dire que les valeurs montent parfaitement ensemble, zéro qu'elles n'ont rien à voir l'une avec l'autre, et moins un que l'une monte quand l'autre descend. On rangera le résultat dans une variable nommée corr_matrix.

1monthly = pd.DataFrame({
2    "rainfall_mm": rainfall_mm,
3    "lion_sightings": lion_sightings,
4    "elephant_sightings": elephant_sightings
5})
6
7corr_matrix = monthly.corr()
8print(corr_matrix.round(2))
9#                     rainfall_mm  lion_sightings  elephant_sightings
10# rainfall_mm                1.00            0.85                0.71
11# lion_sightings             0.85            1.00                0.47
12# elephant_sightings         0.71            0.47                1.00

Trois colonnes numériques ont donné un tableau de trois sur trois. La diagonale ne contient que des uns, puisque chaque colonne s'accorde à cent pour cent avec elle-même, et le tableau entier est symétrique par rapport à cette diagonale. Fais attention à une condition qu'on oublie vite : corr ne travaille que sur des nombres. S'il restait ne serait-ce qu'une colonne de texte dans monthly, l'appel s'arrêterait sur ValueError: could not convert string to float, et il faudrait filtrer les colonnes numériques en amont avec le paramètre numeric_only=True ou la méthode select_dtypes vue à la leçon précédente. Un second piège guette juste là : s'il ne te reste qu'une colonne numérique après le tri, tu obtiens une matrice de un sur un avec un unique 1, formellement correcte et informativement vide. Une matrice de corrélation utile réclame au moins deux colonnes numériques.

sns.heatmap, la matrice en couleurs

Trois sur trois, ton regard le lit encore ; vingt sur vingt, c'est un mur de chiffres. La carte de chaleur, la heatmap, remplace chaque nombre par une couleur, ce qui fait ressortir les liens forts tout seuls. C'est la fonction heatmap de Seaborn qui la dessine. Le paramètre annot réinscrit les nombres sur les cases, cmap choisit la palette - "coolwarm" peint les valeurs négatives en bleu et les positives en rouge - et center indique quelle valeur doit tomber au milieu de l'échelle de couleurs, ici zéro.

Dans sa forme la plus courte, cet appel se compose de six morceaux qu'il vaut mieux connaître par coeur : sns, ., heatmap, (, corr_matrix, ). D'abord le raccourci de la bibliothèque, puis le point, le nom de la fonction, la parenthèse ouvrante, la matrice qu'on lui passe, et la parenthèse fermante. Les paramètres supplémentaires ne s'ajoutent qu'après le nom de la matrice, avant la parenthèse fermante.

1plt.figure(figsize=(8, 6))
2sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", center=0)
3plt.title("Correlations des observations de la reserve")
4plt.show()

La case la plus chaude en dehors de la diagonale relie la pluie aux observations de lions : 0,85, un lien très fort. Les éléphants réagissent moins nettement à la pluie, 0,71, et entre lions et éléphants il ne reste que 0,47. La carte de chaleur n'a rien calculé, tous ces nombres étaient déjà dans corr_matrix et elle s'est contentée de les peindre pour qu'on puisse les comparer d'un seul regard. Souviens-toi enfin du piège classique : une corrélation forte dit que deux choses avancent ensemble, pas que l'une provoque l'autre. La pluie ne fabrique pas des lions, elle attire le gibier au point d'eau, là où il est plus facile de le voir.

Quatre graphiques sur une seule page

Un rapport d'expédition tient rarement en un seul dessin. Plutôt que d'enregistrer quatre fichiers séparés, tu peux découper la feuille en grille avec subplots, à qui tu donnes un nombre de lignes et un nombre de colonnes. Elle renvoie deux choses d'un coup : l'objet de la feuille entière, traditionnellement appelé fig, et le tableau des zones de dessin, appelé axes. On atteint une zone précise comme une case de matrice NumPy, axes[ligne, colonne], en comptant à partir de zéro. Attention aux noms de méthodes : une zone n'a pas de title mais un set_title, pas de xlabel mais un set_xlabel, parce que c'est un objet et non le module plt.

1fig, axes = plt.subplots(2, 2, figsize=(12, 10))
2
3axes[0, 0].bar(species, populations)
4axes[0, 0].set_title("Populations")
5
6axes[0, 1].pie(populations, labels=species, autopct="%1.1f%%")
7axes[0, 1].set_title("Parts")
8
9axes[1, 0].hist(lion_weights, bins=6)
10axes[1, 0].set_title("Distribution du poids")
11
12axes[1, 1].scatter(rainfall_mm, lion_sightings)
13axes[1, 1].set_title("Pluie et observations")
14
15plt.tight_layout()
16plt.show()

Les quatre graphiques de la leçon ont atterri sur une seule feuille, en deux lignes et deux colonnes. Les noms des fonctions de dessin n'ont pas changé d'une lettre, c'est toujours bar, pie, hist et scatter, appelés sur une zone au lieu de plt. tight_layout écarte les graphiques juste ce qu'il faut pour que les titres et les noms d'axes ne se chevauchent pas, et c'est tout ce qu'elle fait. À la fin tu appelles quand même un seul plt.show(), parce que la grille entière ne forme qu'un seul dessin. Avec une seule zone, l'enchaînement est le même en plus court : fig, ax = plt.subplots(), puis ax.plot(x, y), puis ax.set_xlabel(...) et ax.set_ylabel(...), et plt.show() pour terminer.

Résumé

  • Le module de dessin s'importe toujours ainsi : import matplotlib.pyplot as plt. Les écritures import pyplot as plt, from matplotlib import plot et import matplotlib as plt mènent à une erreur, la dernière seulement au premier dessin.
  • Le diagramme en barres se trace avec plt.bar(). plt.bars(), plt.column() et plt.histogram() n'existent pas.
  • Le dessin s'affiche avec plt.show(), caractère par caractère : plt, ., show, (, ).
  • plt.plot pour une évolution dans le temps, plt.bar pour comparer des catégories, plt.hist pour la distribution d'une variable, plt.pie pour des parts d'un tout, plt.scatter pour le lien entre deux nombres.
  • L'enregistrement se fait avec plt.savefig("nom.png"), toujours avant plt.show().
  • Seaborn s'importe sous le nom sns, accepte un DataFrame et ajoute les graphiques statistiques.
  • sns.boxplot montre la distribution des données avec ses quartiles et ses valeurs aberrantes ; il ne dessine pas de cadres autour du texte, ne sert pas à tracer des rectangles et ne combine pas des graphiques dans des cadres.
  • La carte de chaleur des corrélations se construit en six morceaux : sns, ., heatmap, (, corr_matrix, ).
  • Plusieurs graphiques sur une même page s'organisent avec plt.subplots(lignes, colonnes), et chaque zone se décrit avec set_title, set_xlabel et set_ylabel.

Dans la prochaine leçon, nous mettrons ces graphiques au service d'une reconnaissance appelée EDA, où l'histogramme et le boxplot serviront à débusquer les trous et les valeurs aberrantes d'un jeu de données tout frais. Pour l'instant, retiens une seule chose : un graphique n'ajoute pas la moindre information aux données, il les dispose simplement de façon à ce que le regard repère la piste qu'une colonne de nombres ne te montrera jamais.

Code de cette leçon : main.py
1# ===========================================
2# Labo Safari : Visualisation Matplotlib
3# ===========================================
4# Visualise les données d'expédition avec des graphiques
5# Matplotlib pour présenter les tendances des populations.
6
7import matplotlib.pyplot as plt
8
9# --- Données d'observations mensuelles ---
10months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun"]
11lion_sightings = [8, 12, 15, 10, 18, 22]
12elephant_sightings = [5, 7, 6, 9, 11, 8]
13
14# --- Créer un graphique en courbe ---
15plt.figure(figsize=(10, 6))
16plt.plot(months, lion_sightings, marker="o", label="Lions", color="gold")
17plt.plot(months, elephant_sightings, marker="s", label="Elephants", color="gray")
18
19plt.title("Observations Safari - Tendance mensuelle")
20plt.xlabel("Mois")
21plt.ylabel("Nombre d'observations")
22plt.legend()
23plt.grid(True, alpha=0.3)
24plt.show()
25
26# TODO : Crée un diagramme en barres montrant les populations d'animaux
27# Utilise ces catégories et valeurs :
28# animals = ["Lion", "Elephant", "Giraffe", "Zebra", "Cheetah"]
29# populations = [190, 85, 150, 230, 45]
30#
31# plt.figure(figsize=(10, 6))
32# plt.bar(...)
33# plt.title("Populations des animaux du Safari")
34# plt.xlabel(...)
35# plt.ylabel(...)
36# plt.show()
37
38# TODO : Crée un nuage de points poids vs vitesse
39# weights = [190, 5400, 1200, 350, 50]
40# speeds = [80, 40, 60, 65, 120]
41#
42# plt.figure(figsize=(8, 6))
43# plt.scatter(...)
44# plt.title("Poids vs vitesse chez les animaux du Safari")
45# plt.xlabel(...)
46# plt.ylabel(...)
47# plt.show()
48

Tu as repéré une erreur dans cette leçon ?

Teste tes connaissances

Réponds aux questions de cette leçon. Choisis une réponse pour voir tout de suite si elle est correcte.

  1. 1. Quel est l'import standard du module pyplot de Matplotlib ?

  2. 2. Quelle fonction plt utilises-tu pour créer un diagramme en barres ?

Voici 2 des 3 questions de cette leçon. Réponds aux autres dans le jeu.

Tâches pratiques dans le jeu

  • Éditeur de code

    Utilise plt.bar() et plt.show() pour créer un graphique à partir des données species et populations.

  • Tri horizontal

    Remets dans l'ordre le code pour afficher un graphique :

  • Clique dans l'ordre

    Clique sur les boutons pour créer une heatmap de corrélation :

Articles utiles