matplotlib et pandas June 1, 2025
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
import IPython
introduction ¶ Les fonctionnalités de matplotlib ont été intégrées avec la librairie pandas afin de faciliter leur utilisation à partir de dataframe et de séries
nous allons illustrer les quelques fonctions sur un petit exemple(référez-vous à la documentation pour aller plus loin dans les réglages -nous resterons ici très simples)
une pandas.DataFrame est une table de données en dimension 2matplotlib lui apporte des facilités de visualisations
de données des pandas.Series e.g plot, boxplots (boîtes à moustaches), histogrammes, barcharts...
de nuages de points 2D ou 3D impliquant plusieurs colonnes
nous allons voir quelques plots intéressants sur l’exemple des iris
la dataframe des iris ¶ lisons le csv des iris avec pandas affichons les 2 premières lignes
df = pd.read_csv('data/iris.csv')
df.head(2)
->
SepalLength SepalWidth PetalLength PetalWidth Name
0 5.1 3.5 1.4 0.2 Iris-setosa
1 4.9 3.0 1.4 0.2 Iris-setosaaffichons les petites statistiques elles donnent une bonne première idée des données, de leur répartition...
df.head(2)
df.describe()
-> SepalLength SepalWidth PetalLength PetalWidth
count 150.000000 150.000000 150.000000 150.000000
mean 5.843333 3.054000 3.758667 1.198667
std 0.828066 0.433594 1.764420 0.763161
min 4.300000 2.000000 1.000000 0.100000
25% 5.100000 2.800000 1.600000 0.300000
50% 5.800000 3.000000 4.350000 1.300000
75% 6.400000 3.300000 5.100000 1.800000
max 7.900000 4.400000 6.900000 2.500000remarquez que describe par défaut n’affiche que les 4 colonnes numériques
(dans le code ci-dessous, pour plus de lisibilité nous utilisons l’affichage html avec IPython.display.display )
# le code
df = pd.read_csv('data/iris.csv')
IPython.display.display( df.head(2) )
IPython.display.display( df.describe() )visualisation de la dataframe - df.plot() ¶ la méthode plot des objets de type pandas.DataFrame i.e. pandas.DataFrame.plot permet une première visualisation simple, rapide et informative des colonnes numériques qui apporte beaucoup d’informations sur ces données
la fonction pandas.DataFrame.plot possède les mêmes paramètres que la fonction matplotlib.pyplot.plot elle permet les mêmes réglages (en fait elles utilisent toutes les deux la même fonction)
boxplots des colonnes df.boxplot ¶ un boxplot montre: le minimum, le maximum, la médiane, le premier et le troisième quartile les (éventuels) outliers
les outliers sont les points en dehors de bornes décidées par boxplot ces points sont potentiellement aberrants ou simplement des extrêmes (lire la doc pour connaître les bornes considérées)
nous pouvons dessiner les boxplots ensemble ils sont alors mis à la même échelle
on remarque des outliers dans la colonne des SepalWidth
nous pouvons dessiner les boxplots des colonnes indiquées par une liste
df.boxplot(['SepalWidth', 'PetalWidth'])nous pouvons regrouper les boxplots suivant les valeurs d’une colonne (cela nous rappelle groupby, c’est très utile)
df.boxplot(['PetalLength'], by='Name')nous remarquons que les iris Setosa ont des PetalLength bien plus petits que ceux des autres types d’iris ce qui permet de les discriminer des deux autres types d’iris
# le code
df.boxplot()
plt.show() # afin de ne pas superposer les plots
df.boxplot(['SepalWidth', 'PetalWidth']);
plt.show()
df.boxplot(['PetalLength'], by='Name')
plt.tight_layout() # le paddinghistogrammes df.hist ¶ un histogramme donne la distribution des valeurs d’une colonne
les valeurs de la colonne sont rangées dans des intervalles - ou bins les nombres de valeurs par intervalle sont affichés
on remarque 3 pics dans SepalLength correspondent-ils aux 3 types d’iris ?
on peut dessiner l’histogramme d’une seule colonne on peut changer des paramètres comme le nombre d’intervalles bins=, la couleur color=...
df.hist('SepalLength', bins=10, color='lightblue')# le code
df.hist()
df.hist('SepalLength', bins = 10, color='lightblue')
plt.title('histogramme de la colonne SepalLength');barchart df.plot.bar() ¶ prenons un exemple pour illustrer le dessin des barres la dataframe df_animals des animaux, leur vitesse et leur durée de vie
barres verticales
barres horizontales
une seule colonne
df_animals.plot.barh(x='lifespan')une colonne
df_animals.plot.barh(x='lifespan')une colonne en fonction d’une autre
df_animals.plot.barh(x='lifespan')utilisez le help
# le code
df_animals = pd.DataFrame({'speed' : [0.1, 17.5, 40, 48, 52, 69, 88],
'lifespan' : [2, 8, 70, 1.5, 25, 12, 28]},
index = ['snail', 'pig', 'elephant',
'rabbit', 'giraffe', 'coyote', 'horse'])
df_animals.plot.bar()
df_animals.plot.barh()
df_animals.plot.bar(x='lifespan', y='speed');le type de la colonne 'Name' ¶ revenons à nos iris
affichons la description de la colonne des types de fleurs 'Name'
df[['Name']].describe()
->
Name
count 150
unique 3
top Iris-versicolor
freq 50nous avons 3 noms uniques donc 3 types différents d’iris
comptons le nombre d’observations par valeurs dans cette colonne
df['Name'].value_counts()
->
Iris-versicolor 50
Iris-virginica 50
Iris-setosa 50
Name: Name, dtype: int64on remarque que les 3 types sont bien répartis dans les données (1/3)
affichons le type des éléments de la colonne Name
O signifie object
ce type est object ici ce sont des objets de type chaînes de caractères
pourtant ... la colonne des noms des iris est plutôt une colonne de type catégorie avec ses 3 valeurs Iris-versicolor, Iris-virginica et Iris-setosa
nous allons changer le type des éléments de la série df['Name']
# le code
IPython.display.display( df[['Name']].describe() )
df['Name'].value_counts()#le code
df['Name'].dtypeencodage de 'Name' en catégories ¶ la colonne df['Name'] est de type pandas.Series
avec la méthode astype('category') on crée une nouvelle série mais de type catégoriel
col = df['Name'].astype('category')
col.head(2)
->
0 Iris-setosa
1 Iris-setosa
Name: Name, dtype: category
Categories (3, object): ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']remarquez l’ordre dans la liste des catégories ('Iris-setosa' est à l’indice 0...)
Nous allons maintenant extraire de cette nouvelle colonne les codes générés par pandas pour les trois catégories d’iris
à savoir: sur une colonne de type category
cat permet d’accéder aux méthodes et attributs des objets de type category (comme str le permet sur les colonnes d’éléments de type str)
l’attribut codes des colonnes category permet d’accéder aux codes numériques donné par pandas aux 3 catégories (dans l’ordre de la liste des catégories)
on crée une nouvelle colonne 'Name-code' avec ces codes on regarde ce qu’elle contient
df['Name-code'] = col.cat.codes
df['Name-code'].value_counts()
->
Name-code
0 50
1 50
2 50
Name: count, dtype: int64À quoi cela va-t-il nous servir ? par exemple à améliorer nos visualisations où ces codes peuvent servir de code-couleur lors d’affichage des Iris (nous y reviendrons lors de scatter)
# le code
col = df['Name'].astype('category')
col.head(2)0 Iris-setosa
1 Iris-setosa
Name: Name, dtype: category
Categories (3, object): ['Iris-setosa', 'Iris-versicolor', 'Iris-virginica']
# le code
df['Name-code'] = col.cat.codes
df['Name-code'].value_counts()Name-code
0 50
1 50
2 50
Name: count, dtype: int64
# et en une seul ligne
df['Name-code'] = df['Name'].astype('category').cat.codes
nuages de points df.plot.scatter ¶ pour mettre en valeur des informations sur nos données on peut dessiner en 2D les colonnes les unes par rapport aux autres avec pandas.DataFrame.plot.scatter
dessinons les 'SepalLength' en fonction des 'SepalWidth'
df.plot.scatter(x='SepalLength', y='SepalWidth')on peut le faire directement en matplotlib.pyplot.plot mais il faut alors préciser tous les paramètres (noms des axes...)
plt.scatter(df['SepalLength'], df['SepalWidth'])avec le paramètre c=
on peut changer la couleur
mais on peut aussi, indiquer une couleur par point
une idée du code couleur intéressant à utiliser ?
oui, on peut représenter ainsi la catégorie des points
chacun des 3 types d’iris, est une valeur entière différente
on va considérer cette valeur comme un code dans une table de couleurs
attention au code 0 (il peut être très peu coloré dans certaines tables)
df.plot.scatter(x='SepalLength', y='SepalWidth', c='Name-code', cmap='viridis');avec matplotlib.pyplot.plot mais vous n’avez alors que les paramètres par défaut
plt.scatter(df['SepalLength'], df['SepalWidth'], c=df['Name-code'], cmap='viridis')
plt.colorbar() # sinon pas de jolie barre de couleuravec le paramètre s= on peut changer la taille des points ou la taille de chaque point par exemple, donnons leur une taille proportionnelle à la largeur des pétales
plt.scatter(df['SepalLength'], df['SepalWidth'], c=df['Name-code'], s=df['PetalWidth']);ainsi sur un même dessin on peut voir 4 informations le nuage, la couleur et la taille des points
il faut travailler un peu les paramètres pour que ce soit visible (là la taille est trop peu différenciée, multipliez la)
# le code
df.plot.scatter(x='SepalLength', y='SepalWidth');# le code
plt.scatter(df['SepalLength'], df['SepalWidth']);
# plt.xlabel('SepalLength')
# plt.ylabel('SepalWidth')# le code
df.plot.scatter(x='SepalLength', y='SepalWidth', c='Name-code', cmap='viridis');# le code
plt.scatter(df['SepalLength'], df['SepalWidth'], c=df['Name-code'], cmap='viridis')
plt.colorbar();# le code
plt.scatter(df['SepalLength'], df['SepalWidth'], c=df['Name-code'], s=df['PetalWidth']*50);fabriquer son propre type category ¶ pour les avancés
avec la technique précédente on n’a pas de contrôle sur l’ordre parmi les différentes catégories
imaginez que nous avons maintenant une colonne dont les valeurs uniques sontbad, average, good, excellent cette colonne est clairement une colonne de type catégorie ordonnée
on peut définir son propre type catégoriel avec la fonctionpd.CategoricalDtype() dont le paramètre ordered permet de dire si la catégorie est ordonnée ou non
en l’appliquand à la colonne des 'Names' je peux ensuite trier la dataframe sur cette colonne
iris_ord_cat = pd.CategoricalDtype(
categories=['Iris-versicolor', 'Iris-virginica', 'Iris-setosa'],
ordered=True)
df.Name = df.Name.astype(iris_ord_cat)
df.sort_values(by='Name')iris_ord_cat = pd.CategoricalDtype(
categories=['Iris-versicolor', 'Iris-virginica', 'Iris-setosa'],
ordered=True)
iris_ord_catCategoricalDtype(categories=['Iris-versicolor', 'Iris-virginica', 'Iris-setosa'], ordered=True, categories_dtype=object)
df.Name = df.Name.astype(iris_ord_cat)
df.sort_values(by='Name').head(4)