Comment créer un graphique avec deux axes Y à l'aide de Matplotlib ?

Published: 31 mai 2014

Updated: 14 décembre 2024

Tags: Matplotlib;

DMCA.com Protection Status

Introduction

Créer un graphique avec deux axes Y peut être utile pour visualiser des données qui partagent le même axe X mais ont des échelles ou des unités différentes. Matplotlib, une bibliothèque puissante de traçage pour Python, offre des méthodes simples pour y parvenir. Voici un guide étape par étape.

Ajouter un second axe Y avec la méthode twinx

Importer les bibliothèques nécessaires

Commencez par importer Matplotlib et d'autres bibliothèques nécessaires.

1
2
import matplotlib.pyplot as plt
import numpy as np

Générer des données d'exemple

Pour la démonstration, créez deux ensembles de données à visualiser sur le même graphique.

1
2
3
x = np.linspace(0, 10, 100)  # Axe X commun
y1 = np.sin(x)  # Premier ensemble de données
y2 = np.exp(x / 3)  # Deuxième ensemble de données

Créer le graphique principal

Utilisez la méthode subplots pour créer une figure et un axe pour le premier axe Y.

1
2
3
4
5
6
7
fig, ax1 = plt.subplots()

# Tracer le premier ensemble de données
ax1.plot(x, y1, 'b-', label='Onde sinusoïdale')
ax1.set_xlabel('Axe X')
ax1.set_ylabel('Sinus', color='b')
ax1.tick_params(axis='y', labelcolor='b')

Ajouter un second axe Y

Utilisez la méthode twinx pour ajouter un second axe Y qui partage le même axe X.

1
2
3
4
5
6
ax2 = ax1.twinx()  # Créer un second axe partageant l'axe X

# Tracer le deuxième ensemble de données
ax2.plot(x, y2, 'r-', label='Croissance exponentielle')
ax2.set_ylabel('Exponentielle', color='r')
ax2.tick_params(axis='y', labelcolor='r')

Ajouter un titre et une légende

Personnalisez le graphique avec des titres et des légendes.

1
2
3
4
5
fig.suptitle('Graphique avec deux axes Y')

# Facultatif : ajouter des légendes
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')

Afficher le graphique

Enfin, affichez le graphique avec la méthode show.

1
plt.show()

Code complet

Voici le script complet :

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
import matplotlib.pyplot as plt
import numpy as np

# Générer des données
x = np.linspace(0, 10, 100)
y1 = np.sin(x)
y2 = np.exp(x / 3)

# Créer le graphique pour le premier axe Y
fig, ax1 = plt.subplots()
ax1.plot(x, y1, 'b-', label='Onde sinusoïdale')
ax1.set_xlabel('Axe X')
ax1.set_ylabel('Sinus', color='b')
ax1.tick_params(axis='y', labelcolor='b')

# Ajouter un second axe Y
ax2 = ax1.twinx()
ax2.plot(x, y2, 'r-', label='Croissance exponentielle')
ax2.set_ylabel('Exponentielle', color='r')
ax2.tick_params(axis='y', labelcolor='r')

# Ajouter le titre et les légendes
fig.suptitle('Graphique avec deux axes Y')
ax1.legend(loc='upper left')
ax2.legend(loc='upper right')

# Afficher le graphique
plt.show()

Sortie

Le graphique résultant aura :
- Un axe X partagé.
- La courbe sinusoïdale (y1) sur l'axe Y gauche avec des étiquettes et une ligne bleues.
- La courbe exponentielle (y2) sur l'axe Y droit avec des étiquettes et une ligne rouges.

How to Create a Plot with Two Y-Axes Using Matplotlib ?
How to Create a Plot with Two Y-Axes Using Matplotlib ?

Notes importantes

  • Utilisez des couleurs différentes pour chaque axe afin d'améliorer la lisibilité.
  • Assurez-vous que les ensembles de données ont une relation logique ou justifiée pour être visualisés ensemble.
  • Si une personnalisation supplémentaire est nécessaire, la documentation exhaustive de Matplotlib peut être une ressource utile.

Un autre exemple

Code pour créer un graphique avec deux axes Y visualisant les concentrations atmosphériques de CO₂ et les anomalies de température mondiales. Le graphique combine un tracé linéaire pour le CO₂ et un graphique en barres pour les anomalies de température.

Importer les bibliothèques

1
2
3
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np
  • pandas : Utilisé pour charger et traiter les données de séries chronologiques.
  • matplotlib.pyplot : Utilisé pour réaliser les graphiques.
  • numpy : Fournit des utilitaires numériques.

Charger et préparer les données de CO₂

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
# Charger les données de CO₂
co2_data = pd.read_csv(
    "./inputs/co2_mm_mlo.csv",  # Remplacer par le chemin de votre fichier
    skiprows=40,                # Sauter les lignes d'en-tête spécifiques au jeu de données
    na_values=["-99.99"]        # Gérer les valeurs manquantes
)
co2_data = co2_data.dropna()  # Supprimer les lignes avec des données manquantes

# Créer une colonne datetime à partir de l'année et du mois
co2_data['date'] = pd.to_datetime(co2_data[['year', 'month']].assign(day=1))
  • Charge les données mensuelles de CO₂ de l'Observatoire de Mauna Loa.
  • Nettoie le jeu de données et combine l'année et le mois en un objet datetime pour le tracé.

Charger et préparer les données des anomalies de température

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Charger les données des anomalies de température
temp_data = pd.read_csv(
    "./inputs/GLB.Ts+dSST.csv",  # Remplacer par le chemin de votre fichier
    skiprows=1                   # Sauter la ligne d'en-tête
)

# Renommer et sélectionner les colonnes pertinentes
temp_data = temp_data.rename(columns={"Year": "year", "J-D": "anomaly"})
temp_data = temp_data[['year', 'anomaly']]

# Ajouter une colonne datetime (mi-année pour les données annuelles)
temp_data['date'] = pd.to_datetime(temp_data['year'].astype(str) + '-07-01')
  • Charge les données des anomalies de température mondiales et les nettoie en renommant et en sélectionnant les colonnes nécessaires.
  • Convertit la colonne year en un objet datetime pour l'alignement avec les données de CO₂.

Aligner et filtrer les données

1
2
3
4
5
6
7
8
9
# Filtrer les données pour la plage de dates partagée
start_date = max(co2_data['date'].min(), temp_data['date'].min())
end_date = min(co2_data['date'].max(), temp_data['date'].max())
co2_filtered = co2_data[(co2_data['date'] >= start_date) & (co2_data['date'] <= end_date)]
temp_filtered = temp_data[(temp_data['date'] >= start_date) & (temp_data['date'] <= end_date)]

# Assurer que la colonne 'anomaly' est numérique et supprimer les lignes invalides
temp_filtered['anomaly'] = pd.to_numeric(temp_filtered['anomaly'], errors='coerce')
temp_filtered = temp_filtered.dropna(subset=['anomaly'])
  • Aligne les données de CO₂ et de température en filtrant la plage de dates qui se chevauche.
  • Convertit la colonne anomaly en numérique et supprime les lignes invalides.

Séparer les anomalies positives et négatives

1
2
3
# Séparer les données en anomalies positives et négatives
positive_anomalies = temp_filtered[temp_filtered['anomaly'] > 0]
negative_anomalies = temp_filtered[temp_filtered['anomaly'] <= 0]
  • Divise les données des anomalies de température en deux sous-ensembles : anomalies positives (rouge) et anomalies négatives (bleu).

Créer le graphique

1
2
3
4
5
6
7
8
fig, ax1 = plt.subplots(figsize=(10, 6))

# Tracer les données de CO₂
ax1.plot(co2_filtered['year'], co2_filtered['average'], 'g-', label='CO₂ (ppm)')
ax1.set_xlabel('Année')
ax1.set_ylabel('Concentration de CO₂ (ppm)', color='g')
ax1.tick_params(axis='y', colors='g')
ax1.legend(loc='upper left')
  • Crée le premier axe Y pour les données de CO₂ avec un tracé linéaire vert.

Ajouter un second axe Y pour les anomalies de température

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
# Ajouter un second axe pour les anomalies de température
ax2 = ax1.twinx()

# Tracer les barres avec différentes couleurs pour les anomalies
ax2.bar(positive_anomalies['year'], positive_anomalies['anomaly'], color='r', alpha=0.7, label='Anomalie positive')
ax2.bar(negative_anomalies['year'], negative_anomalies['anomaly'], color='b', alpha=0.7, label='Anomalie négative')

# Définir l'étiquette et le format de l'axe Y secondaire
ax2.set_ylabel('Anomalie de température (°C)', color='k')
ax2.tick_params(axis='y', colors='k')
ax2.legend(loc='upper right')
  • Ajoute un second axe Y pour les anomalies de température.
  • Utilise un graphique en barres avec des barres rouges pour les anomalies positives et bleues pour les anomalies négatives.

Ajouter un titre et afficher le graphique

1
2
3
4
5
# Ajouter le titre et la grille
plt.title('CO₂ atmosphérique et anomalies de température mondiales')
plt.grid()
plt.tight_layout()
plt.show()
  • Ajoute un titre, une grille, et ajuste la mise en page pour éviter les chevauchements.

Code complet

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
import pandas as pd
import matplotlib.pyplot as plt
import numpy as np

# Charger les données de CO₂
co2_data = pd.read_csv(
    "./inputs/co2_mm_mlo.csv",  # Remplacer par le chemin de votre fichier
    skiprows=40,
    na_values=["-99.99"])

co2_data = co2_data.dropna()
co2_data['date'] = pd.to_datetime(co2_data[['year', 'month']].assign(day=1))

# Charger les données des anomalies de température
temp_data = pd.read_csv(
    "./inputs/GLB.Ts+dSST.csv",  # Remplacer par le chemin de votre fichier
    skiprows=1
)

temp_data = temp_data.rename(columns={"Year": "year", "J-D": "anomaly"})
temp_data = temp_data[['year', 'anomaly']]
temp_data['date'] = pd.to_datetime(temp_data['year'].astype(str) + '-07-01')  # Mi-année pour les données annuelles

start_date = max(co2_data['date'].min(), temp_data['date'].min())
end_date = min(co2_data['date'].max(), temp_data['date'].max())
co2_filtered = co2_data[(co2_data['date'] >= start_date) & (co2_data['date'] <= end_date)]
temp_filtered = temp_data[(temp_data['date'] >= start_date) & (temp_data['date'] <= end_date)]

# Assurer que la colonne 'anomaly' est numérique
temp_filtered['anomaly'] = pd.to_numeric(temp_filtered['anomaly'], errors='coerce')

# Supprimer les lignes avec des valeurs NaN dans 'anomaly' après conversion
temp_filtered = temp_filtered.dropna(subset=['anomaly'])

# Séparer les données en anomalies positives et négatives
positive_anomalies = temp_filtered[temp_filtered['anomaly'] > 0]
negative_anomalies = temp_filtered[temp_filtered['anomaly'] <= 0]

# Tracé
fig, ax1 = plt.subplots(figsize=(10, 6))

# Tracer les données de CO₂
ax1.plot(co2_filtered['year'], co2_filtered['average'], 'g-', label='CO₂ (ppm)')
ax1.set_xlabel('Année')
ax1.set_ylabel('Concentration de CO₂ (ppm)', color='g')
ax1.tick_params(axis='y', colors='g')
ax1.legend(loc='upper left')

# Ajouter un second axe pour les anomalies de température
ax2 = ax1.twinx()

# Tracer les barres avec différentes couleurs
ax2.bar(positive_anomalies['year'], positive_anomalies['anomaly'], color='r', alpha=0.7, label='Anomalie positive')
ax2.bar(negative_anomalies['year'], negative_anomalies['anomaly'], color='b', alpha=0.7, label='Anomalie négative')

# Définir l'étiquette et le format de l'axe Y secondaire
ax2.set_ylabel('Anomalie de température (°C)', color='k')
ax2.tick_params(axis='y', colors='k')
ax2.legend(loc='upper right')

# Ajouter le titre et la grille
plt.title('CO₂ atmosphérique et anomalies de température mondiales')
plt.grid()
plt.tight_layout()
plt.show()

Sortie

  • Axe Y gauche : Concentration de CO₂ (ppm) sous forme de tracé linéaire vert.
  • Axe Y droit : Anomalies de température (°C) sous forme de barres rouges et bleues.
  • Le graphique fournit une visualisation claire de la relation entre les niveaux de CO₂ et les anomalies de température mondiales au fil du temps.

How to Create a Plot with Two Y-Axes Using Matplotlib ?
How to Create a Plot with Two Y-Axes Using Matplotlib ?

Notes clés

  • Remplacez les chemins de fichier ("./inputs/co2_mm_mlo.csv" et "./inputs/GLB.Ts+dSST.csv") par les emplacements réels des fichiers sur votre système.
  • Assurez-vous que les formats de données correspondent aux attentes du code, ou ajustez les noms des colonnes et la logique de parsing si nécessaire.

Références

Image

of