Python
Créer facilement des histogrammes en Python : guide pour les débutants

Créer facilement des histogrammes en Python : guide pour les débutants

MoeNagy Dev

Qu'est-ce qu'un histogramme ?

Un histogramme est une représentation graphique de la distribution d'un ensemble de données. C'est un outil fondamental pour l'analyse et la visualisation des données, car il fournit un moyen clair et intuitif de comprendre les schémas et les caractéristiques sous-jacentes d'un ensemble de données.

Un histogramme est créé en divisant la plage de valeurs de l'ensemble de données en un ensemble de bin (ou intervalles) et en comptant le nombre de points de données qui tombent dans chaque bin. Le graphique résultant affiche la fréquence ou le nombre de points de données dans chaque bin, donnant une représentation visuelle de la distribution des données.

Les histogrammes sont particulièrement utiles pour comprendre la forme, la tendance centrale et la dispersion d'un ensemble de données. Ils peuvent aider à identifier des schémas, tels que la présence de multiples pics (indiquant une distribution multimodale), l'asymétrie (symétrie) et les valeurs aberrantes (points de données qui se trouvent en dehors de la distribution principale).

Préparation des données

Pour créer un histogramme en Python, nous devrons importer les bibliothèques nécessaires et générer des données d'exemple avec lesquelles travailler.

import numpy as np
import matplotlib.pyplot as plt
 
# Générer des données d'exemple
data = np.random.normal(0, 1, 1000)

Dans cet exemple, nous utilisons la fonction numpy.random.normal() pour générer 1 000 points de données à partir d'une distribution normale standard (moyenne = 0, écart type = 1). Vous pouvez remplacer cela par votre propre ensemble de données ou utiliser une distribution différente pour explorer la visualisation de l'histogramme.

Tracé de base de l'histogramme

La façon la plus simple de créer un histogramme en Python consiste à utiliser la fonction plt.hist() de la bibliothèque Matplotlib.

# Créer un histogramme
plt.hist(data, bins=30, color='blue', alpha=0.5)
 
# Ajouter des étiquettes et un titre
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme des données d\'exemple')
 
# Afficher le graphique
plt.show()

Dans cet exemple, nous créons un histogramme avec 30 bacs, en utilisant une couleur bleue et une transparence (alpha) de 0,5. Vous pouvez personnaliser l'histogramme en ajustant le nombre de bacs, la largeur des bacs, la couleur et la transparence.

Personnalisation de l'histogramme

Définition du nombre de bacs

Le nombre de bacs dans un histogramme est un paramètre important qui peut affecter significativement l'apparence et l'interprétation du tracé. Vous pouvez ajuster le nombre de bacs en utilisant le paramètre bins dans la fonction plt.hist().

# Histogramme avec 10 bacs
plt.hist(data, bins=10, color='green', alpha=0.7)
plt.show()
 
# Histogramme avec 50 bacs
plt.hist(data, bins=50, color='red', alpha=0.7)
plt.show()

Augmenter le nombre de bacs peut fournir plus de détails sur la distribution des données, mais cela peut également entraîner une apparence plus bruyante ou "hachée". Diminuer le nombre de bacs peut lisser l'histogramme, mais peut masquer certains des détails les plus fins.

Ajustement de la largeur des bacs

En plus du nombre de bacs, vous pouvez également ajuster la largeur des bacs pour contrôler le niveau de détail dans l'histogramme.

# Histogramme avec une largeur de bac de 0.2
plt.hist(data, bins=np.arange(-3, 3, 0.2), color='orange', alpha=0.7)
plt.show()
 
# Histogramme avec une largeur de bac de 0.5
plt.hist(data, bins=np.arange(-3, 3, 0.5), color='purple', alpha=0.7)
plt.show()

Dans cet exemple, nous utilisons la fonction np.arange() pour créer les limites des bacs, en spécifiant les valeurs de début, de fin et d'étape.

Modification de la couleur et de la transparence de l'histogramme

Vous pouvez personnaliser davantage l'apparence de l'histogramme en ajustant la couleur et la transparence des barres.

# Histogramme avec une couleur et une transparence différentes
plt.hist(data, bins=30, color='red', alpha=0.3)
plt.show()

L'expérimentation avec différentes couleurs et paramètres de transparence peut vous aider à créer des histogrammes visuellement attrayants et à communiquer efficacement la distribution des données.

Personnalisation avancée de l'histogramme

Au-delà du tracé de base de l'histogramme, vous pouvez personnaliser davantage la visualisation pour la rendre plus informative et plus attrayante.

Ajout d'étiquettes et de titre

Ajouter des étiquettes claires et un titre descriptif peut aider le lecteur à comprendre le contexte et le but de l'histogramme.

# Ajouter des étiquettes et un titre
plt.hist(data, bins=30, color='blue', alpha=0.5)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme des données d\'exemple')
plt.show()

Ajustement des échelles des axes

En fonction de la plage et de la distribution de vos données, vous voudrez peut-être ajuster les échelles des axes x et y pour mieux adapter les données.

# Ajuster les échelles des axes x et y
plt.hist(data, bins=30, color='blue', alpha=0.5)
plt.xlim(-3, 3)
plt.ylim(0, 150)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme des données d\'exemple')
plt.show()

Dans cet exemple, nous fixons la plage de l'axe x de -3 à 3 et la plage de l'axe y de 0 à 150 pour mieux adapter la distribution des données.

Affichage des lignes de grille

L'ajout de lignes de grille peut aider le lecteur à mieux interpréter l'histogramme et à identifier des points de données ou des fréquences spécifiques.

# Ajouter des lignes de grille
plt.hist(data, bins=30, color='blue', alpha=0.5)
plt.grid(True)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme des données d\'exemple')
plt.show()

Enregistrer l'histogramme sous la forme d'un fichier image

Une fois satisfait de l'histogramme, vous pouvez l'enregistrer sous la forme d'un fichier image pour une utilisation dans des rapports, des présentations ou d'autres applications.

# Enregistrer l'histogramme sous forme de fichier image
plt.hist(data, bins=30, color='blue', alpha=0.5)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme des données d\'exemple')
plt.savefig('histogramme.png', dpi=300)

Dans cet exemple, nous enregistrons l'histogramme sous la forme d'un fichier PNG avec une résolution de 300 points par pouce (dpi).

Normalisation de l'histogramme

Les histogrammes peuvent également être normalisés pour représenter la fréquence relative ou la densité de probabilité des données au lieu de la fréquence absolue.

# Créer un histogramme normalisé
plt.hist(data, bins=30, density=True, color='blue', alpha=0.5)
plt.xlabel('Valeur')
plt.ylabel('Densité de probabilité')
plt.title('Histogramme normalisé des données d'échantillon')
plt.show()

En définissant le paramètre density=True dans la fonction plt.hist(), l'axe Y de l'histogramme représentera la densité de probabilité au lieu de la fréquence. Cela peut être utile pour comparer des histogrammes de jeux de données avec des échelles différentes ou pour superposer l'histogramme avec une courbe de distribution de probabilité.

Multiples histogrammes sur le même graphique

Vous pouvez tracer plusieurs histogrammes sur la même figure pour comparer les distributions de différents ensembles de données ou variables.

# Générer deux ensembles de données d'échantillon
data1 = np.random.normal(0, 1, 1000)
data2 = np.random.normal(1, 0.5, 1000)
 
# Créer une figure avec deux sous-graphiques
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
 
# Tracer le premier histogramme
ax1.hist(data1, bins=30, color='blue', alpha=0.5)
ax1.set_xlabel('Valeur')
ax1.set_ylabel('Fréquence')
ax1.set_title('Histogramme de l'ensemble de données 1')
 
# Tracer le deuxième histogramme
ax2.hist(data2, bins=30, color='red', alpha=0.5)
ax2.set_xlabel('Valeur')
ax2.set_ylabel('Fréquence')
ax2.set_title('Histogramme de l'ensemble de données 2')
 
# Ajuster l'espacement entre les sous-graphiques
plt.subplots_adjust(wspace=0.4)
plt.show()

Dans cet exemple, nous créons une figure avec deux sous-graphiques, chacun contenant un histogramme pour un ensemble de données différent. Nous ajustons également l'espacement entre les sous-graphiques à l'aide de la fonction plt.subplots_adjust().

Histogrammes avec des données catégorielles

Les histogrammes peuvent également être utilisés pour visualiser la distribution de données catégorielles, bien que l'interprétation soit légèrement différente.

# Générer des données catégorielles aléatoires
categories = ['A', 'B', 'C', 'D', 'E']
data = np.random.choice(categories, 1000)
 
# Créer un histogramme pour les données catégorielles
plt.hist(data, bins=len(categories), edgecolor='black')
plt.xticks(range(len(categories)), categories)
plt.xlabel('Catégorie')
plt.ylabel('Fréquence')
plt.title('Histogramme des données catégorielles')
plt.show()

Dans cet exemple, nous générons 1 000 points de données catégorielles aléatoires et créons un histogramme pour visualiser leur distribution. Le paramètre bins est défini sur le nombre de catégories uniques, et nous utilisons plt.xticks() pour étiqueter l'axe des abscisses avec les noms des catégories.

Histogrammes avec des données continues

Lorsqu'il s'agit de données continues, le choix du nombre de compartiments devient plus critique, car il peut avoir un impact significatif sur l'apparence et l'interprétation de l'histogramme.

# Générer des données continues aléatoires
data = np.random.normal(0, 1, 1000)
 
# Créer un histogramme avec différentes tailles de compartiments
plt.figure(figsize=(12, 4))
 
plt.subplot(1, 2, 1)
plt.hist(data, bins=10, color='blue', alpha=0.5)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme avec 10 compartiments')
 
plt.subplot(1, 2, 2)
plt.hist(data, bins=50, color='red', alpha=0.5)
plt.xlabel('Valeur')
plt.ylabel('Fréquence')
plt.title('Histogramme avec 50 compartiments')
 
plt.subplots_adjust(wspace=0.4)
plt.show()

Dans cet exemple, nous créons deux histogrammes côte à côte avec différents nombres de compartiments (10 et 50) pour illustrer l'impact de la taille des compartiments sur la visualisation des données continues.

Fonctions

Les fonctions sont des blocs de code réutilisables qui effectuent une tâche spécifique. Elles vous permettent de regrouper la logique et de rendre votre code plus modulaire et plus maintenable.

Voici un exemple de fonction qui calcule l'aire d'un rectangle :

def calculate_area(length, width):
    area = length * width
    return area
 
# Appeler la fonction
rect_area = calculate_area(5, 10)
print(rect_area)  # Output: 50

Dans cet exemple, la fonction calculate_area() prend deux paramètres, length (longueur) et width (largeur), et renvoie l'aire calculée. Vous pouvez ensuite appeler la fonction et stocker le résultat dans la variable rect_area.

Les fonctions peuvent également avoir des valeurs de paramètres par défaut et accepter un nombre variable d'arguments :

def print_greeting(name, message="Hello"):
    print(f"{message}, {name}!")
 
print_greeting("Alice")  # Output: Hello, Alice!
print_greeting("Bob", "Hi")  # Output: Hi, Bob!
 
def calculate_sum(*numbers):
    total = 0
    for num in numbers:
        total += num
    return total
 
print(calculate_sum(1, 2, 3))  # Output: 6
print(calculate_sum(4, 5, 6, 7, 8))  # Output: 30

Dans le premier exemple, la fonction print_greeting() a une valeur par défaut pour le paramètre message, qui est utilisée si aucune valeur n'est fournie. Dans le deuxième exemple, la fonction calculate_sum() peut accepter un nombre quelconque d'arguments, qui sont collectés dans un tuple nommé numbers.

Modules et packages

La bibliothèque standard de Python fournit une large gamme de modules intégrés que vous pouvez utiliser dans vos programmes. Vous pouvez également créer vos propres modules et packages pour organiser votre code.

Voici un exemple de comment utiliser le module math :

import math
 
radius = 5
circle_area = math.pi * radius ** 2
print(circle_area)  # Output: 78.53981633974483

Dans cet exemple, nous importons le module math puis utilisons la constante pi et l'opérateur ** pour calculer l'aire d'un cercle.

Vous pouvez également importer des fonctions ou des attributs spécifiques d'un module :

from math import pi, sqrt
 
radius = 5
circle_area = pi * radius ** 2
diagonal = sqrt(radius ** 2 + radius ** 2)
print(circle_area)  # Output: 78.53981633974483
print(diagonal)  # Output: 7.0710678118654755

Ici, nous importons les fonctions pi et sqrt directement depuis le module math, ce qui nous permet de les utiliser sans le préfixe math.. Pour créer votre propre module, il vous suffit d'enregistrer votre code Python dans un fichier avec l'extension .py. Par exemple, vous pouvez créer un fichier my_module.py avec le contenu suivant :

def greet(name):
    print(f"Bonjour, {name} !")
 
def calculate_area(length, width):
    return length * width

Vous pouvez ensuite importer et utiliser les fonctions de votre module :

import my_module
 
my_module.greet("Alice")  # Résultat : Bonjour, Alice !
aire = my_module.calculate_area(5, 10)
print(aire)  # Résultat : 50

Les packages sont un moyen d'organiser vos modules dans une structure hiérarchique. Pour créer un package, vous devez créer un répertoire avec un fichier __init__.py. Ce fichier peut être vide, mais il est nécessaire pour que Python reconnaisse le répertoire en tant que package.

Par exemple, vous pouvez créer un répertoire my_package avec un fichier __init__.py, puis ajouter un fichier my_module.py à l'intérieur du répertoire :

my_package/
    __init__.py
    my_module.py

Vous pouvez ensuite importer et utiliser les fonctions du module à l'intérieur du package :

import my_package.my_module
 
my_package.my_module.greet("Alice")  # Résultat : Bonjour, Alice !
aire = my_package.my_module.calculate_area(5, 10)
print(aire)  # Résultat : 50

Alternativement, vous pouvez utiliser l'instruction from pour importer directement les fonctions du module :

from my_package.my_module import greet, calculate_area
 
greet("Alice")  # Résultat : Bonjour, Alice !
aire = calculate_area(5, 10)
print(aire)  # Résultat : 50

Entrée/Sortie de fichiers

Python propose des fonctions intégrées pour la lecture à partir de fichiers et l'écriture dans des fichiers. Les fonctions les plus couramment utilisées sont open(), read(), write() et close().

Voici un exemple de lecture du contenu d'un fichier :

# Ouvrir le fichier en mode lecture
with open("exemple.txt", "r") as fichier:
    contenu = fichier.read()
    print(contenu)

Dans cet exemple, la fonction open() est utilisée pour ouvrir le fichier exemple.txt en mode lecture ("r"). L'instruction with garantit que le fichier est correctement fermé après l'exécution du bloc de code, même en cas d'exception.

Vous pouvez également lire le fichier ligne par ligne :

with open("exemple.txt", "r") as fichier:
    for ligne in fichier:
        print(ligne.strip())

Cela affichera chaque ligne du fichier, en supprimant les espaces vides au début ou à la fin à l'aide de la méthode strip().

Pour écrire dans un fichier, vous pouvez utiliser la fonction write() :

with open("sortie.txt", "w") as fichier:
    fichier.write("Bonjour, monde !\n")
    fichier.write("Ceci est une nouvelle ligne.\n")

Dans cet exemple, nous ouvrons le fichier sortie.txt en mode écriture ("w"), puis utilisons la fonction write() pour ajouter deux lignes de texte au fichier.

Vous pouvez également ajouter des données à un fichier existant en l'ouvrant en mode ajout ("a"):

with open("sortie.txt", "a") as fichier:
    fichier.write("Ceci est une ligne supplémentaire.\n")

Cela ajoutera une nouvelle ligne à la fin du fichier sortie.txt.

Gestion des exceptions

Le mécanisme de gestion des exceptions de Python vous permet de gérer les erreurs et les situations inattendues dans votre code. Le bloc try-except est utilisé pour capturer et gérer les exceptions.

Voici un exemple de gestion d'une ZeroDivisionError :

try:
    resultat = 10 / 0
except ZeroDivisionError:
    print("Erreur : Division par zéro")

Dans cet exemple, le bloc try tente de diviser 10 par 0, ce qui générera une ZeroDivisionError. Le bloc except capture l'exception et affiche un message d'erreur.

Vous pouvez également gérer plusieurs exceptions dans un seul bloc except :

try:
    num = int(input("Entrez un nombre : "))
    resultat = 10 / num
except (ValueError, ZeroDivisionError):
    print("Erreur : Entrée non valide ou division par zéro")

Dans cet exemple, le bloc try tente de convertir la saisie de l'utilisateur en entier, puis de diviser 10 par le résultat. Si l'utilisateur entre une valeur non numérique, une ValueError sera générée, et si l'utilisateur entre 0, une ZeroDivisionError sera générée. Le bloc except capture ces deux exceptions et affiche un message d'erreur.

Vous pouvez également utiliser les clauses else et finally avec le bloc try-except :

try:
    num = int(input("Entrez un nombre : "))
    resultat = 10 / num
except ValueError:
    print("Erreur : Entrée non valide")
except ZeroDivisionError:
    print("Erreur : Division par zéro")
else:
    print(f"Le résultat est : {resultat}")
finally:
    print("Le bloc 'try-except' est terminé.")

Dans cet exemple, la clause else est exécutée si aucune exception n'est levée dans le bloc try, et la clause finally est toujours exécutée, indépendamment de la survenue ou non d'une exception.

Conclusion

Dans ce tutoriel, vous avez appris divers concepts de Python, notamment les fonctions, les modules et les packages, l'entrée/sortie de fichiers et la gestion des exceptions. Ce sont des compétences essentielles pour tout programmeur Python, et elles vous aideront à écrire un code plus organisé, plus maintenable et plus robuste.

Souvenez-vous, la meilleure façon d'améliorer vos compétences en Python est de pratiquer. Essayez d'appliquer les concepts que vous avez appris à vos propres projets, et n'hésitez pas à explorer le vaste écosystème de bibliothèques et d'outils Python disponibles. Bonne chance dans votre parcours de programmation Python !