Skip to content

Latest commit

 

History

History
888 lines (696 loc) · 23.2 KB

File metadata and controls

888 lines (696 loc) · 23.2 KB

🔝 Retour au Sommaire

13.3.2 Visualisations interactives avec Plotly

Introduction

Plotly est une bibliothèque de visualisation moderne qui permet de créer des graphiques interactifs de qualité professionnelle. Contrairement à Matplotlib qui génère des graphiques statiques, Plotly permet à l'utilisateur d'interagir avec les données en temps réel : zoom, survol pour voir les valeurs, filtrage, etc.

Pourquoi utiliser Plotly ?

  • Interactivité : zoom, pan, sélection, tooltips automatiques
  • Qualité professionnelle : graphiques prêts pour des présentations et dashboards
  • Facilité d'utilisation : syntaxe intuitive
  • Export facile : HTML, PNG, SVG, PDF
  • Parfait pour le web : intégration simple dans des applications web

Installation

Plotly s'installe facilement avec pip :

pip install plotly

Pour certains exports et fonctionnalités avancées :

pip install kaleido  # Pour exporter en images statiques

Les deux interfaces de Plotly

Plotly propose deux façons de créer des graphiques :

  1. Plotly Express (recommandé pour débuter) : interface simple et rapide
  2. Plotly Graph Objects : interface plus détaillée pour un contrôle total

Nous allons principalement utiliser Plotly Express car il est plus simple et couvre la majorité des besoins.

Importation

import plotly.express as px  
import plotly.graph_objects as go  
import pandas as pd  
import numpy as np  

1. Graphique en ligne interactif

Exemple simple avec Plotly Express

import plotly.express as px  
import numpy as np  

# Données
x = np.linspace(0, 10, 100)  
y = np.sin(x)  

# Création du graphique
fig = px.line(x=x, y=y,
              title='Fonction sinus',
              labels={'x': 'Angle (radians)', 'y': 'sin(x)'})
fig.show()

Fonctionnalités interactives automatiques :

  • Survolez la courbe pour voir les valeurs exactes
  • Zoomez avec la molette ou en sélectionnant une zone
  • Déplacez le graphique (pan)
  • Double-clic pour réinitialiser le zoom

Graphique multi-lignes

import plotly.express as px  
import pandas as pd  
import numpy as np  

# Création d'un DataFrame avec plusieurs séries
x = np.linspace(0, 10, 100)  
df = pd.DataFrame({  
    'x': x,
    'sin': np.sin(x),
    'cos': np.cos(x),
    'tan': np.tan(x)
})

# Transformation pour Plotly (format long)
df_long = df.melt(id_vars='x', var_name='fonction', value_name='valeur')

# Création du graphique
fig = px.line(df_long, x='x', y='valeur', color='fonction',
              title='Fonctions trigonométriques',
              labels={'valeur': 'f(x)', 'x': 'Angle (radians)'})
fig.show()

Graphique avec markers (points)

import plotly.express as px  
import numpy as np  

# Données
x = np.arange(0, 10)  
y = x ** 2  

fig = px.line(x=x, y=y,
              markers=True,  # Ajoute des marqueurs
              title='Fonction quadratique')
fig.update_traces(marker=dict(size=10))  
fig.show()  

2. Nuage de points (Scatter Plot)

Les nuages de points interactifs sont particulièrement utiles pour explorer les relations entre variables.

Exemple basique

import plotly.express as px  
import numpy as np  

# Données
n = 100  
x = np.random.rand(n) * 100  
y = np.random.rand(n) * 100  

fig = px.scatter(x=x, y=y,
                 title='Nuage de points interactif',
                 labels={'x': 'Variable X', 'y': 'Variable Y'})
fig.show()

Scatter avec couleurs et tailles variables

import plotly.express as px  
import pandas as pd  
import numpy as np  

# Création de données
np.random.seed(42)  
n = 100  
df = pd.DataFrame({  
    'x': np.random.rand(n) * 100,
    'y': np.random.rand(n) * 100,
    'taille': np.random.rand(n) * 50,
    'categorie': np.random.choice(['A', 'B', 'C'], n)
})

# Graphique avec couleurs par catégorie et tailles variables
fig = px.scatter(df, x='x', y='y',
                 size='taille',           # Taille des points
                 color='categorie',       # Couleur par catégorie
                 hover_data=['taille'],   # Info au survol
                 title='Nuage de points avec couleurs et tailles')
fig.show()

Exemple avec données réelles : Dataset Iris

import plotly.express as px

# Chargement du dataset Iris (inclus dans Plotly)
df = px.data.iris()

# Graphique interactif
fig = px.scatter(df, x='sepal_width', y='sepal_length',
                 color='species',              # Couleur par espèce
                 size='petal_length',          # Taille selon longueur pétale
                 hover_data=['petal_width'],   # Info supplémentaire
                 title='Dataset Iris - Analyse multidimensionnelle')
fig.show()

3. Diagrammes à barres interactifs

Barres verticales

import plotly.express as px

# Données
produits = ['Produit A', 'Produit B', 'Produit C', 'Produit D', 'Produit E']  
ventes = [23, 45, 56, 78, 34]  

fig = px.bar(x=produits, y=ventes,
             title='Ventes par produit',
             labels={'x': 'Produits', 'y': 'Ventes (en milliers)'},
             color=ventes,  # Gradient de couleur
             color_continuous_scale='blues')
fig.show()

Barres groupées

import plotly.express as px  
import pandas as pd  

# Données
df = pd.DataFrame({
    'Trimestre': ['Q1', 'Q2', 'Q3', 'Q4'] * 2,
    'Année': ['2023', '2023', '2023', '2023', '2024', '2024', '2024', '2024'],
    'Ventes': [20, 35, 30, 35, 25, 32, 34, 40]
})

fig = px.bar(df, x='Trimestre', y='Ventes', color='Année',
             barmode='group',  # Barres groupées
             title='Comparaison des ventes 2023 vs 2024')
fig.show()

Barres empilées

import plotly.express as px  
import pandas as pd  

# Données
df = pd.DataFrame({
    'Mois': ['Jan', 'Fév', 'Mar', 'Avr'] * 3,
    'Région': ['Nord', 'Nord', 'Nord', 'Nord',
               'Sud', 'Sud', 'Sud', 'Sud',
               'Est', 'Est', 'Est', 'Est'],
    'Ventes': [10, 15, 12, 18, 8, 12, 14, 16, 12, 14, 11, 15]
})

fig = px.bar(df, x='Mois', y='Ventes', color='Région',
             barmode='stack',  # Barres empilées
             title='Ventes par région et par mois')
fig.show()

Barres horizontales

import plotly.express as px

# Données (top langages de programmation)
langages = ['Python', 'JavaScript', 'Java', 'C#', 'C++', 'PHP', 'TypeScript']  
popularite = [29.9, 19.5, 17.3, 7.1, 6.7, 6.1, 3.0]  

fig = px.bar(y=langages, x=popularite,
             orientation='h',  # Horizontal
             title='Popularité des langages de programmation 2024',
             labels={'x': 'Pourcentage d\'utilisation', 'y': 'Langage'},
             color=popularite,
             color_continuous_scale='viridis')
fig.show()

4. Histogrammes interactifs

import plotly.express as px  
import numpy as np  

# Données : distribution normale
data = np.random.randn(1000)

fig = px.histogram(x=data,
                   nbins=50,
                   title='Distribution normale',
                   labels={'x': 'Valeur', 'y': 'Fréquence'})
fig.show()

Histogrammes superposés

import plotly.express as px  
import pandas as pd  
import numpy as np  

# Données
np.random.seed(42)  
df = pd.DataFrame({  
    'valeur': np.concatenate([
        np.random.normal(100, 15, 500),
        np.random.normal(120, 15, 500)
    ]),
    'groupe': ['Groupe A'] * 500 + ['Groupe B'] * 500
})

fig = px.histogram(df, x='valeur', color='groupe',
                   nbins=30,
                   title='Comparaison de deux distributions',
                   barmode='overlay',  # Superposition
                   opacity=0.6)
fig.show()

5. Box plots (Boîtes à moustaches)

Les box plots sont excellents pour visualiser la distribution et détecter les valeurs aberrantes.

import plotly.express as px  
import pandas as pd  
import numpy as np  

# Création de données
np.random.seed(42)  
df = pd.DataFrame({  
    'Catégorie': np.repeat(['A', 'B', 'C'], 100),
    'Valeurs': np.concatenate([
        np.random.normal(50, 10, 100),
        np.random.normal(60, 15, 100),
        np.random.normal(55, 8, 100)
    ])
})

fig = px.box(df, x='Catégorie', y='Valeurs',
             title='Distribution des valeurs par catégorie',
             color='Catégorie')
fig.show()

Ce que montre un box plot :

  • La ligne centrale : médiane
  • La boîte : 50% des données (quartiles Q1 et Q3)
  • Les moustaches : étendue des données
  • Les points : valeurs aberrantes

6. Diagramme circulaire (Pie Chart)

import plotly.express as px

# Données
langages = ['Python', 'JavaScript', 'Java', 'C++', 'Autres']  
parts = [30, 25, 20, 15, 10]  

fig = px.pie(values=parts, names=langages,
             title='Langages de programmation les plus utilisés',
             hole=0.3)  # Crée un donut chart (0 = pie classique)
fig.show()

Pie chart avec personnalisation

import plotly.graph_objects as go

# Données
labels = ['Python', 'JavaScript', 'Java', 'C++', 'Autres']  
values = [30, 25, 20, 15, 10]  
colors = ['#636EFA', '#EF553B', '#00CC96', '#AB63FA', '#FFA15A']  

fig = go.Figure(data=[go.Pie(
    labels=labels,
    values=values,
    marker=dict(colors=colors),
    pull=[0.1, 0, 0, 0, 0],  # "Tire" la première tranche
    textinfo='label+percent',
    hoverinfo='label+value+percent'
)])

fig.update_layout(title='Langages de programmation')  
fig.show()  

7. Graphiques 3D

Plotly excelle dans la création de graphiques 3D interactifs.

Scatter 3D

import plotly.express as px  
import pandas as pd  
import numpy as np  

# Données
np.random.seed(42)  
n = 200  
df = pd.DataFrame({  
    'x': np.random.randn(n),
    'y': np.random.randn(n),
    'z': np.random.randn(n),
    'couleur': np.random.rand(n)
})

fig = px.scatter_3d(df, x='x', y='y', z='z',
                    color='couleur',
                    title='Nuage de points 3D interactif')
fig.show()

Fonctionnalités 3D :

  • Rotation libre avec la souris
  • Zoom avant/arrière
  • Pan (déplacement)

Surface 3D

import plotly.graph_objects as go  
import numpy as np  

# Création d'une surface mathématique
x = np.linspace(-5, 5, 50)  
y = np.linspace(-5, 5, 50)  
X, Y = np.meshgrid(x, y)  
Z = np.sin(np.sqrt(X**2 + Y**2))  

fig = go.Figure(data=[go.Surface(x=X, y=Y, z=Z, colorscale='viridis')])  
fig.update_layout(  
    title='Surface 3D : sin(sqrt(x² + y²))',
    scene=dict(
        xaxis_title='X',
        yaxis_title='Y',
        zaxis_title='Z'
    )
)
fig.show()

8. Heatmaps (Cartes de chaleur)

Les heatmaps sont parfaites pour visualiser des matrices et des corrélations.

import plotly.express as px  
import numpy as np  

# Création d'une matrice de corrélation
np.random.seed(42)  
data = np.random.rand(10, 10)  

fig = px.imshow(data,
                labels=dict(x='Variable X', y='Variable Y', color='Valeur'),
                title='Carte de chaleur',
                color_continuous_scale='RdBu')
fig.show()

Matrice de corrélation

import plotly.express as px  
import pandas as pd  

# Dataset Iris
df = px.data.iris()

# Calcul de la matrice de corrélation
corr_matrix = df[['sepal_length', 'sepal_width', 'petal_length', 'petal_width']].corr()

fig = px.imshow(corr_matrix,
                labels=dict(color='Corrélation'),
                x=corr_matrix.columns,
                y=corr_matrix.columns,
                title='Matrice de corrélation - Dataset Iris',
                color_continuous_scale='RdBu',
                zmin=-1, zmax=1,  # Échelle de -1 à 1
                text_auto=True)   # Affiche les valeurs
fig.show()

9. Graphiques animés

Plotly permet de créer facilement des animations pour montrer l'évolution dans le temps.

Scatter animé

import plotly.express as px

# Dataset Gapminder (inclus dans Plotly)
df = px.data.gapminder()

# Graphique animé
fig = px.scatter(df,
                 x='gdpPercap',
                 y='lifeExp',
                 size='pop',           # Taille = population
                 color='continent',     # Couleur = continent
                 hover_name='country',  # Nom au survol
                 log_x=True,            # Échelle log pour X
                 size_max=60,
                 animation_frame='year', # Animation par année
                 animation_group='country',
                 range_x=[100, 100000],
                 range_y=[25, 90],
                 title='Évolution mondiale : Espérance de vie vs PIB (1952-2007)')
fig.show()

Contrôles d'animation :

  • Bouton Play/Pause
  • Curseur pour naviguer dans le temps
  • Vitesse ajustable

Bar chart animé

import plotly.express as px

# Données
df = px.data.gapminder()

# Top 10 pays par population
df_filtered = df[df['country'].isin(['China', 'India', 'United States',
                                      'Indonesia', 'Brazil', 'Pakistan',
                                      'Nigeria', 'Bangladesh', 'Russia', 'Japan'])]

fig = px.bar(df_filtered,
             x='pop',
             y='country',
             orientation='h',
             animation_frame='year',
             range_x=[0, 1.5e9],
             title='Évolution de la population des 10 pays les plus peuplés')
fig.show()

10. Subplots : Plusieurs graphiques

Plotly permet de créer des tableaux de bord avec plusieurs graphiques.

Avec Plotly Express (facets)

import plotly.express as px

# Dataset
df = px.data.iris()

# Création automatique de subplots avec facet
fig = px.scatter(df, x='sepal_width', y='sepal_length',
                 color='species',
                 facet_col='species',  # Une colonne par espèce
                 title='Iris - Analyse par espèce')
fig.show()

Avec Graph Objects (contrôle total)

import plotly.graph_objects as go  
from plotly.subplots import make_subplots  
import numpy as np  

# Création d'une grille 2x2
fig = make_subplots(
    rows=2, cols=2,
    subplot_titles=('Ligne', 'Barres', 'Scatter', 'Histogramme')
)

# Graphique 1 : Ligne
x = np.linspace(0, 10, 100)  
fig.add_trace(go.Scatter(x=x, y=np.sin(x), mode='lines', name='sin(x)'),  
              row=1, col=1)

# Graphique 2 : Barres
fig.add_trace(go.Bar(x=['A', 'B', 'C'], y=[3, 7, 2], name='Barres'),
              row=1, col=2)

# Graphique 3 : Scatter
fig.add_trace(go.Scatter(x=np.random.rand(50), y=np.random.rand(50),
                         mode='markers', name='Points'),
              row=2, col=1)

# Graphique 4 : Histogramme
fig.add_trace(go.Histogram(x=np.random.randn(500), name='Distribution'),
              row=2, col=2)

fig.update_layout(height=600, title_text='Tableau de bord multi-graphiques')  
fig.show()  

11. Personnalisation avancée

Thèmes prédéfinis

Plotly propose plusieurs thèmes élégants :

import plotly.express as px  
import plotly.io as pio  

# Liste des thèmes disponibles
print(pio.templates)

# Application d'un thème
pio.templates.default = 'plotly_dark'  # Thème sombre

# Création d'un graphique
df = px.data.iris()  
fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species')  
fig.show()  

Thèmes populaires :

  • 'plotly' : thème par défaut (clair)
  • 'plotly_dark' : thème sombre
  • 'seaborn' : style Seaborn
  • 'simple_white' : minimaliste
  • 'ggplot2' : style ggplot

Personnalisation du layout

import plotly.express as px  
import numpy as np  

# Données
x = np.linspace(0, 10, 100)  
y = np.sin(x)  

fig = px.line(x=x, y=y)

# Personnalisation complète
fig.update_layout(
    title={
        'text': 'Mon graphique personnalisé',
        'x': 0.5,  # Centré
        'xanchor': 'center',
        'font': {'size': 24, 'color': 'darkblue'}
    },
    xaxis_title='Axe X (unité)',
    yaxis_title='Axe Y (unité)',
    font=dict(family='Arial', size=14),
    plot_bgcolor='#f0f0f0',  # Couleur de fond
    paper_bgcolor='white',
    hovermode='x unified',    # Tooltip unifié
    showlegend=True,
    legend=dict(
        x=1,
        y=1,
        bgcolor='rgba(255,255,255,0.8)'
    )
)

# Personnalisation des axes
fig.update_xaxes(showgrid=True, gridwidth=1, gridcolor='lightgray')  
fig.update_yaxes(showgrid=True, gridwidth=1, gridcolor='lightgray')  

fig.show()

Annotations et formes

import plotly.graph_objects as go  
import numpy as np  

# Données
x = np.linspace(0, 10, 100)  
y = np.sin(x)  

fig = go.Figure()  
fig.add_trace(go.Scatter(x=x, y=y, mode='lines'))  

# Ajout d'annotations
fig.add_annotation(
    x=np.pi/2, y=1,
    text='Maximum',
    showarrow=True,
    arrowhead=2,
    arrowcolor='red',
    font=dict(size=14, color='red')
)

# Ajout de formes
fig.add_shape(
    type='rect',
    x0=0, y0=-0.5, x1=5, y1=0.5,
    fillcolor='lightgreen',
    opacity=0.2,
    line_width=0
)

fig.update_layout(title='Graphique avec annotations et formes')  
fig.show()  

12. Export et sauvegarde

Sauvegarde en HTML

import plotly.express as px

df = px.data.iris()  
fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species')  

# Sauvegarde en HTML (interactif)
fig.write_html('mon_graphique.html')

Sauvegarde en image statique

import plotly.express as px

df = px.data.iris()  
fig = px.scatter(df, x='sepal_width', y='sepal_length', color='species')  

# Nécessite kaleido : pip install kaleido
fig.write_image('mon_graphique.png', width=1200, height=800)  
fig.write_image('mon_graphique.pdf')  
fig.write_image('mon_graphique.svg')  

13. Intégration avec Pandas

Plotly s'intègre parfaitement avec Pandas pour une analyse rapide.

import plotly.express as px  
import pandas as pd  
import numpy as np  

# Création d'un DataFrame
np.random.seed(42)  
dates = pd.date_range('2024-01-01', periods=365, freq='D')  
df = pd.DataFrame({  
    'date': dates,
    'ventes': np.cumsum(np.random.randn(365)) + 100,
    'visites': np.cumsum(np.random.randn(365)) + 500
})

# Graphique rapide
fig = px.line(df, x='date', y=['ventes', 'visites'],
              title='Évolution des ventes et visites en 2024')
fig.show()

Exemple complet : Dashboard interactif

Voici un exemple complet combinant plusieurs graphiques dans un dashboard :

import plotly.graph_objects as go  
from plotly.subplots import make_subplots  
import pandas as pd  
import numpy as np  

# Génération de données fictives
np.random.seed(42)  
dates = pd.date_range('2024-01-01', periods=12, freq='ME')  
df = pd.DataFrame({  
    'mois': [d.strftime('%b') for d in dates],
    'ventes': np.random.randint(50, 150, 12),
    'objectif': [100] * 12,
    'region_nord': np.random.randint(20, 60, 12),
    'region_sud': np.random.randint(15, 50, 12),
    'region_est': np.random.randint(10, 40, 12)
})

# Création du dashboard avec subplots
fig = make_subplots(
    rows=2, cols=2,
    subplot_titles=('Évolution des ventes mensuelles',
                    'Ventes vs Objectif',
                    'Distribution des ventes',
                    'Répartition par région'),
    specs=[[{'type': 'scatter'}, {'type': 'bar'}],
           [{'type': 'histogram'}, {'type': 'pie'}]]
)

# 1. Ligne : Évolution des ventes
fig.add_trace(
    go.Scatter(x=df['mois'], y=df['ventes'],
               mode='lines+markers',
               name='Ventes réelles',
               line=dict(color='blue', width=3)),
    row=1, col=1
)
fig.add_trace(
    go.Scatter(x=df['mois'], y=df['objectif'],
               mode='lines',
               name='Objectif',
               line=dict(color='red', dash='dash')),
    row=1, col=1
)

# 2. Barres : Comparaison ventes/objectif
colors = ['green' if v >= 100 else 'orange' for v in df['ventes']]  
fig.add_trace(  
    go.Bar(x=df['mois'], y=df['ventes'],
           name='Ventes',
           marker_color=colors),
    row=1, col=2
)

# 3. Histogramme : Distribution
fig.add_trace(
    go.Histogram(x=df['ventes'],
                 nbinsx=8,
                 name='Distribution',
                 marker_color='purple'),
    row=2, col=1
)

# 4. Pie : Répartition par région
regions = ['Nord', 'Sud', 'Est']  
ventes_regions = [df['region_nord'].sum(),  
                  df['region_sud'].sum(),
                  df['region_est'].sum()]
fig.add_trace(
    go.Pie(labels=regions, values=ventes_regions,
           hole=0.3),
    row=2, col=2
)

# Mise à jour du layout
fig.update_layout(
    height=800,
    showlegend=True,
    title_text='Dashboard Commercial 2024',
    title_font_size=20
)

# Personnalisation des axes
fig.update_xaxes(title_text='Mois', row=1, col=1)  
fig.update_yaxes(title_text='Ventes', row=1, col=1)  
fig.update_xaxes(title_text='Mois', row=1, col=2)  
fig.update_yaxes(title_text='Ventes', row=1, col=2)  
fig.update_xaxes(title_text='Ventes', row=2, col=1)  
fig.update_yaxes(title_text='Fréquence', row=2, col=1)  

fig.show()

Comparaison : Matplotlib vs Plotly

Aspect Matplotlib Plotly
Interactivité Statique (par défaut) Interactif natif
Facilité d'utilisation Plus complexe Plus simple (Express)
Qualité visuelle Bonne, mais nécessite configuration Excellente par défaut
Performance Rapide pour images statiques Peut être lent avec beaucoup de données
Export PNG, PDF, SVG HTML, PNG, PDF, SVG
Utilisation web Difficile Native
Personnalisation Très détaillée Bonne, mais moins granulaire
Courbe d'apprentissage Moyenne Facile

Quand utiliser Plotly ?

  • Dashboards interactifs
  • Présentations
  • Applications web
  • Exploration de données
  • Graphiques 3D

Quand utiliser Matplotlib ?

  • Publications scientifiques
  • Images statiques haute résolution
  • Personnalisation extrême
  • Intégration avec des scripts

Bonnes pratiques

  1. Privilégier Plotly Express pour la simplicité
  2. Utiliser des titres et labels explicites
  3. Choisir les bonnes couleurs (palette accessible)
  4. Ne pas surcharger le graphique d'informations
  5. Tester l'interactivité avant de partager
  6. Optimiser les performances pour les gros datasets (échantillonnage)
  7. Sauvegarder en HTML pour conserver l'interactivité
  8. Utiliser des thèmes cohérents dans un projet

Ressources complémentaires

Conclusion

Plotly est un outil puissant qui révolutionne la visualisation de données en Python grâce à son interactivité native. Avec Plotly Express, créer des graphiques professionnels devient un jeu d'enfant. Les graphiques interactifs permettent une exploration plus approfondie des données et sont particulièrement adaptés aux présentations et aux applications web.

Dans vos projets :

  • Utilisez Matplotlib pour des graphiques statiques destinés à des publications
  • Utilisez Plotly pour des dashboards interactifs et l'exploration de données

La combinaison des deux bibliothèques vous donne un arsenal complet pour toute visualisation de données en Python !

⏭️ Introduction à l'analyse exploratoire