---
title: "Seaborn Lineplot : guide complet des graphiques en courbes avec sns.lineplot()"
description: "Maîtrisez seaborn lineplot avec des exemples pratiques couvrant plusieurs courbes, les intervalles de confiance, hue, style, les marqueurs, la visualisation de séries temporelles et la personnalisation."
date: 2026-02-11
author: soren
ogImage:
language: en
tag: Seaborn
---
# Seaborn Lineplot : guide complet des graphiques en courbes avec sns.lineplot()
import BlogHeader from '../../../components/blog-header';
<BlogHeader />
Les graphiques en courbes sont essentiels pour visualiser des tendances, des séries temporelles et des relations entre variables continues. Pourtant, produire des courbes de qualité “publication” qui communiquent clairement les insights nécessite souvent une configuration matplotlib importante et du style appliqué manuellement. Les data scientists perdent des heures à ajuster les couleurs des lignes, gérer les légendes et formater les axes, alors qu’ils devraient se concentrer sur l’analyse.
La fonction `lineplot()` de Seaborn résout ce problème en offrant une interface de haut niveau pour créer de superbes graphiques en courbes avec un minimum de code. Elle gère automatiquement l’agrégation statistique, les intervalles de confiance, les palettes de couleurs et le style visuel, tout en restant hautement personnalisable pour des cas d’usage avancés.
Ce guide couvre tout : des courbes de base aux visualisations avancées multi-séries avec un style personnalisé. Vous apprendrez à créer des graphiques professionnels qui communiquent efficacement les insights de vos données.
import BlogSuggestion from '../../../components/blog-suggestion';
<BlogSuggestion />
## Comprendre les bases de sns.lineplot()
La fonction `sns.lineplot()` crée des graphiques en courbes à partir de pandas DataFrames ou de tableaux (arrays). Elle agrège automatiquement les observations multiples pour chaque valeur de x et affiche des intervalles de confiance par défaut.
```python copy
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
# Create sample data
df = pd.DataFrame({
'time': range(10),
'value': [1, 3, 2, 5, 4, 6, 5, 7, 6, 8]
})
# Basic lineplot
sns.lineplot(data=df, x='time', y='value')
plt.title('Basic Line Plot')
plt.show()Cela crée un graphique en courbes épuré avec des libellés d’axes générés automatiquement à partir des noms de colonnes. La fonction gère la mise en forme des données, l’échelle et le style visuel sans configuration manuelle.
Paramètres clés et syntaxe
La fonction sns.lineplot() accepte des données sous plusieurs formats et propose de nombreuses options de personnalisation :
sns.lineplot(
data=None, # DataFrame, array, or dict
x=None, # Column name or vector for x-axis
y=None, # Column name or vector for y-axis
hue=None, # Grouping variable for color
size=None, # Grouping variable for line width
style=None, # Grouping variable for line style
palette=None, # Color palette
markers=False, # Add markers to data points
dashes=True, # Use dashed lines for styles
ci=95, # Confidence interval (deprecated in newer versions)
errorbar=('ci', 95), # Error representation
legend='auto', # Legend display
ax=None # Matplotlib axes object
)Lorsque vous travaillez avec des DataFrames, utiliser des noms de colonnes pour les paramètres x et y rend le code plus lisible :
# Create multi-observation dataset
data = pd.DataFrame({
'day': [1, 2, 3, 1, 2, 3, 1, 2, 3],
'sales': [100, 150, 120, 110, 145, 125, 105, 155, 130],
'store': ['A', 'A', 'A', 'B', 'B', 'B', 'C', 'C', 'C']
})
# Plot with automatic aggregation
sns.lineplot(data=data, x='day', y='sales')
plt.title('Average Sales by Day (with 95% CI)')
plt.xlabel('Day of Week')
plt.ylabel('Sales ($)')
plt.show()La fonction calcule automatiquement la moyenne des ventes par jour et affiche les intervalles de confiance sous forme de bande ombrée autour de la ligne.
Tracer plusieurs courbes avec Hue
Le paramètre hue crée des lignes distinctes pour différents groupes de vos données, en attribuant automatiquement des couleurs différentes :
# Multiple stores on same plot
fig, ax = plt.subplots(figsize=(10, 6))
sns.lineplot(
data=data,
x='day',
y='sales',
hue='store', # Separate line for each store
palette='Set2'
)
plt.title('Sales Comparison Across Stores')
plt.xlabel('Day of Week')
plt.ylabel('Sales ($)')
plt.legend(title='Store', loc='upper left')
plt.show()Cela crée trois lignes de couleurs distinctes avec une légende générée automatiquement. Le paramètre palette contrôle le jeu de couleurs.
Pour des scénarios de regroupement plus complexes :
# Multiple grouping variables
customer_data = pd.DataFrame({
'month': [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3],
'revenue': [5000, 5500, 6000, 4800, 5200, 5800, 6200, 6800, 7200, 6000, 6500, 7000],
'segment': ['Premium', 'Premium', 'Premium', 'Standard', 'Standard', 'Standard',
'Premium', 'Premium', 'Premium', 'Standard', 'Standard', 'Standard'],
'region': ['North', 'North', 'North', 'North', 'North', 'North',
'South', 'South', 'South', 'South', 'South', 'South']
})
# Use hue for segment, style for region
sns.lineplot(
data=customer_data,
x='month',
y='revenue',
hue='segment',
style='region',
markers=True,
dashes=False
)
plt.title('Revenue by Segment and Region')
plt.xlabel('Month')
plt.ylabel('Revenue ($)')
plt.show()Personnaliser les styles de ligne avec le paramètre Style
Le paramètre style fait varier l’apparence des lignes via différents motifs de tirets ou types de lignes :
# Temperature data with different sensors
temp_data = pd.DataFrame({
'hour': list(range(24)) * 3,
'temperature': [15, 14, 13, 12, 12, 13, 15, 17, 19, 21, 23, 24,
25, 26, 25, 24, 22, 20, 18, 17, 16, 15, 15, 14] * 3,
'sensor': ['Sensor_A'] * 24 + ['Sensor_B'] * 24 + ['Sensor_C'] * 24,
'location': ['Indoor'] * 24 + ['Outdoor'] * 24 + ['Basement'] * 24
})
# Add some variation
import numpy as np
np.random.seed(42)
temp_data['temperature'] = temp_data['temperature'] + np.random.normal(0, 1, len(temp_data))
fig, ax = plt.subplots(figsize=(12, 6))
sns.lineplot(
data=temp_data,
x='hour',
y='temperature',
hue='location',
style='location',
markers=True,
dashes=True,
palette='tab10'
)
plt.title('24-Hour Temperature Monitoring')
plt.xlabel('Hour of Day')
plt.ylabel('Temperature (°C)')
plt.legend(title='Location')
plt.grid(True, alpha=0.3)
plt.show()Différents styles de ligne aident à distinguer les groupes lors d’une impression en niveaux de gris ou pour des considérations d’accessibilité.
Ajouter des marqueurs aux points de données
Les marqueurs mettent en évidence des points de données individuels le long de la courbe, utile pour des données clairsemées ou pour souligner des observations spécifiques :
# Quarterly earnings data
earnings = pd.DataFrame({
'quarter': ['Q1', 'Q2', 'Q3', 'Q4'] * 3,
'earnings': [2.1, 2.3, 2.5, 2.4, 2.2, 2.4, 2.6, 2.7, 2.3, 2.5, 2.8, 2.9],
'year': ['2023'] * 4 + ['2024'] * 4 + ['2025'] * 4
})
sns.lineplot(
data=earnings,
x='quarter',
y='earnings',
hue='year',
markers=True,
marker='o', # Specific marker style
markersize=8,
linewidth=2.5,
palette='deep'
)
plt.title('Quarterly Earnings per Share')
plt.xlabel('Quarter')
plt.ylabel('EPS ($)')
plt.ylim(2.0, 3.0)
plt.legend(title='Year')
plt.grid(True, alpha=0.3)
plt.show()Vous pouvez spécifier des styles de marqueurs par groupe :
# Custom markers for different groups
sns.lineplot(
data=earnings,
x='quarter',
y='earnings',
hue='year',
style='year',
markers=['o', 's', '^'], # Different marker per year
markersize=10,
dashes=False
)
plt.title('Earnings Trend with Distinct Markers')
plt.show()Travailler avec les intervalles de confiance et bandes d’erreur
Seaborn calcule automatiquement des intervalles de confiance lorsqu’il existe plusieurs observations pour chaque valeur de x. Cette agrégation statistique aide à communiquer l’incertitude des données :
# Experimental data with replicates
experiment = pd.DataFrame({
'concentration': [0.1, 0.5, 1.0, 2.0, 5.0] * 10,
'response': np.random.lognormal(mean=[1, 1.5, 2, 2.5, 3] * 10, sigma=0.3),
'replicate': list(range(10)) * 5
})
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# 95% confidence interval (default)
sns.lineplot(data=experiment, x='concentration', y='response',
errorbar=('ci', 95), ax=axes[0])
axes[0].set_title('95% Confidence Interval')
# Standard deviation
sns.lineplot(data=experiment, x='concentration', y='response',
errorbar='sd', ax=axes[1])
axes[1].set_title('Standard Deviation')
# No error bars
sns.lineplot(data=experiment, x='concentration', y='response',
errorbar=None, ax=axes[2])
axes[2].set_title('No Error Bars')
plt.tight_layout()
plt.show()Le paramètre errorbar prend en charge plusieurs représentations :
('ci', 95): intervalle de confiance à 95 %('pi', 95): intervalle de prédiction à 95 %'sd': écart-type'se': erreur standard('pi', 50): intervalle interquartileNone: aucune représentation de l’erreur
Personnaliser les couleurs avec des palettes
Le paramètre palette contrôle les couleurs des lignes via des palettes nommées ou des listes de couleurs personnalisées :
# Stock price comparison
stocks = pd.DataFrame({
'date': pd.date_range('2025-01-01', periods=60),
'price': np.random.randn(60).cumsum() + 100,
'ticker': ['AAPL'] * 60
})
stocks = pd.concat([
stocks,
pd.DataFrame({
'date': pd.date_range('2025-01-01', periods=60),
'price': np.random.randn(60).cumsum() + 150,
'ticker': ['GOOGL'] * 60
}),
pd.DataFrame({
'date': pd.date_range('2025-01-01', periods=60),
'price': np.random.randn(60).cumsum() + 200,
'ticker': ['MSFT'] * 60
})
])
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
# Built-in palette
sns.lineplot(data=stocks, x='date', y='price', hue='ticker',
palette='Set1', ax=axes[0, 0])
axes[0, 0].set_title('Set1 Palette')
# Custom colors
custom_colors = {'AAPL': '#FF6B6B', 'GOOGL': '#4ECDC4', 'MSFT': '#45B7D1'}
sns.lineplot(data=stocks, x='date', y='price', hue='ticker',
palette=custom_colors, ax=axes[0, 1])
axes[0, 1].set_title('Custom Color Mapping')
# Colorblind-safe palette
sns.lineplot(data=stocks, x='date', y='price', hue='ticker',
palette='colorblind', ax=axes[1, 0])
axes[1, 0].set_title('Colorblind Palette')
# Dark palette
sns.lineplot(data=stocks, x='date', y='price', hue='ticker',
palette='dark', ax=axes[1, 1])
axes[1, 1].set_title('Dark Palette')
plt.tight_layout()
plt.show()Options de palettes populaires :
'deep','muted','pastel','bright','dark','colorblind''Set1','Set2','Set3','Paired','tab10''viridis','plasma','inferno','magma','cividis'
Visualisation de séries temporelles
Seaborn lineplot excelle pour visualiser des séries temporelles avec un formatage automatique des dates :
# Website traffic data
dates = pd.date_range('2025-01-01', periods=180, freq='D')
traffic = pd.DataFrame({
'date': dates,
'visits': 1000 + np.random.randn(180).cumsum() * 50 + np.sin(np.arange(180) / 7) * 200,
'source': ['Organic'] * 180
})
# Add paid traffic
paid = pd.DataFrame({
'date': dates,
'visits': 500 + np.random.randn(180).cumsum() * 30,
'source': ['Paid'] * 180
})
traffic = pd.concat([traffic, paid])
fig, ax = plt.subplots(figsize=(14, 6))
sns.lineplot(
data=traffic,
x='date',
y='visits',
hue='source',
palette={'Organic': '#2ecc71', 'Paid': '#e74c3c'},
linewidth=2
)
plt.title('Website Traffic Over Time', fontsize=16, fontweight='bold')
plt.xlabel('Date', fontsize=12)
plt.ylabel('Daily Visits', fontsize=12)
plt.legend(title='Traffic Source', title_fontsize=11, fontsize=10)
plt.grid(True, alpha=0.3, linestyle='--')
# Format x-axis dates
import matplotlib.dates as mdates
ax.xaxis.set_major_formatter(mdates.DateFormatter('%b %Y'))
ax.xaxis.set_major_locator(mdates.MonthLocator(interval=1))
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()Pour des données avec un index datetime :
# Create time series with datetime index
ts_data = pd.DataFrame({
'value': np.random.randn(365).cumsum() + 50
}, index=pd.date_range('2025-01-01', periods=365))
# Reset index to use in lineplot
ts_data_reset = ts_data.reset_index()
ts_data_reset.columns = ['date', 'value']
sns.lineplot(data=ts_data_reset, x='date', y='value')
plt.title('Time Series with Datetime Index')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()Tracer plusieurs courbes à partir de données au format wide
Les DataFrames au format wide stockent différentes variables dans des colonnes séparées. Seaborn peut les tracer directement :
# Wide format data
wide_data = pd.DataFrame({
'month': range(1, 13),
'Product_A': [100, 120, 115, 130, 140, 135, 150, 160, 155, 170, 180, 175],
'Product_B': [80, 85, 90, 95, 100, 105, 110, 115, 120, 125, 130, 135],
'Product_C': [60, 65, 70, 68, 75, 80, 85, 90, 88, 95, 100, 105]
})
# Method 1: Melt to long format
long_data = wide_data.melt(id_vars='month', var_name='Product', value_name='Sales')
sns.lineplot(data=long_data, x='month', y='Sales', hue='Product')
plt.title('Product Sales Comparison')
plt.xlabel('Month')
plt.ylabel('Sales')
plt.show()Sinon, tracez directement depuis le format wide :
# Method 2: Plot each column separately
fig, ax = plt.subplots(figsize=(10, 6))
for column in ['Product_A', 'Product_B', 'Product_C']:
sns.lineplot(data=wide_data, x='month', y=column, label=column, ax=ax)
plt.title('Product Sales (Wide Format)')
plt.xlabel('Month')
plt.ylabel('Sales')
plt.legend(title='Product')
plt.show()Combiner avec Matplotlib pour une personnalisation avancée
Seaborn lineplot s’intègre parfaitement à matplotlib pour un contrôle fin :
# Create figure with custom styling
fig, ax = plt.subplots(figsize=(12, 7))
# Set overall style
sns.set_style('whitegrid')
sns.set_context('notebook', font_scale=1.2)
# Plot data
performance = pd.DataFrame({
'epoch': list(range(1, 51)) * 2,
'accuracy': np.concatenate([
0.6 + 0.008 * np.arange(50) + np.random.randn(50) * 0.02,
0.55 + 0.009 * np.arange(50) + np.random.randn(50) * 0.025
]),
'model': ['Model_A'] * 50 + ['Model_B'] * 50
})
sns.lineplot(
data=performance,
x='epoch',
y='accuracy',
hue='model',
palette=['#FF6B6B', '#4ECDC4'],
linewidth=2.5,
ax=ax
)
# Customize with matplotlib
ax.set_title('Model Training Performance', fontsize=18, fontweight='bold', pad=20)
ax.set_xlabel('Training Epoch', fontsize=14, fontweight='bold')
ax.set_ylabel('Validation Accuracy', fontsize=14, fontweight='bold')
ax.set_ylim(0.5, 1.0)
ax.yaxis.set_major_formatter(plt.FuncFormatter(lambda y, _: f'{y:.0%}'))
# Add reference line
ax.axhline(y=0.8, color='gray', linestyle='--', linewidth=1.5, alpha=0.7, label='Target (80%)')
# Customize legend
handles, labels = ax.get_legend_handles_labels()
ax.legend(handles, labels, title='Model', title_fontsize=12,
fontsize=11, loc='lower right', framealpha=0.95)
# Add grid customization
ax.grid(True, alpha=0.4, linestyle=':', linewidth=0.8)
ax.set_facecolor('#F8F9FA')
# Add annotations
ax.annotate('Model A reaches 90%',
xy=(45, 0.9), xytext=(35, 0.85),
arrowprops=dict(arrowstyle='->', color='#FF6B6B', lw=1.5),
fontsize=10, color='#FF6B6B', fontweight='bold')
plt.tight_layout()
plt.show()Créer des sous-graphiques avec plusieurs lineplots
Comparez différents aspects des données via des mises en page en sous-graphiques :
# Multi-metric dashboard
metrics = pd.DataFrame({
'time': list(range(100)) * 3,
'cpu_usage': np.random.rand(300) * 60 + 20 + np.sin(np.arange(300) / 10) * 15,
'memory_usage': np.random.rand(300) * 40 + 40 + np.cos(np.arange(300) / 15) * 10,
'disk_io': np.random.rand(300) * 80 + 10 + np.sin(np.arange(300) / 8) * 20,
'server': ['Server_1'] * 100 + ['Server_2'] * 100 + ['Server_3'] * 100
})
fig, axes = plt.subplots(3, 1, figsize=(12, 10), sharex=True)
# CPU Usage
sns.lineplot(data=metrics, x='time', y='cpu_usage', hue='server',
palette='Set2', ax=axes[0], legend=True)
axes[0].set_title('CPU Usage (%)', fontsize=14, fontweight='bold')
axes[0].set_ylabel('Usage (%)')
axes[0].set_xlabel('')
axes[0].axhline(y=80, color='red', linestyle='--', alpha=0.5, label='Threshold')
axes[0].legend(loc='upper left', ncol=4)
# Memory Usage
sns.lineplot(data=metrics, x='time', y='memory_usage', hue='server',
palette='Set2', ax=axes[1], legend=False)
axes[1].set_title('Memory Usage (%)', fontsize=14, fontweight='bold')
axes[1].set_ylabel('Usage (%)')
axes[1].set_xlabel('')
axes[1].axhline(y=80, color='red', linestyle='--', alpha=0.5)
# Disk I/O
sns.lineplot(data=metrics, x='time', y='disk_io', hue='server',
palette='Set2', ax=axes[2], legend=False)
axes[2].set_title('Disk I/O (MB/s)', fontsize=14, fontweight='bold')
axes[2].set_ylabel('Throughput')
axes[2].set_xlabel('Time (seconds)', fontsize=12)
plt.tight_layout()
plt.show()Mises en page en grille pour l’analyse comparative :
# 2x2 comparison grid
fig, axes = plt.subplots(2, 2, figsize=(14, 10))
categories = ['Category_A', 'Category_B', 'Category_C', 'Category_D']
positions = [(0, 0), (0, 1), (1, 0), (1, 1)]
for category, (i, j) in zip(categories, positions):
subset = pd.DataFrame({
'x': range(20),
'y': np.random.randn(20).cumsum() + 10
})
sns.lineplot(data=subset, x='x', y='y', ax=axes[i, j],
marker='o', linewidth=2, color='#3498db')
axes[i, j].set_title(f'{category} Trend', fontweight='bold')
axes[i, j].grid(True, alpha=0.3)
plt.suptitle('Multi-Category Performance Dashboard', fontsize=16, fontweight='bold', y=1.02)
plt.tight_layout()
plt.show()Tableau comparatif : sns.lineplot vs plt.plot vs sns.relplot
| Feature | sns.lineplot() | plt.plot() | sns.relplot(kind="line") |
|---|---|---|---|
| Automatic aggregation | Yes (mean + CI) | No | Yes (mean + CI) |
| DataFrame integration | Native support | Requires array conversion | Native support |
| Multiple groups (hue) | Automatic coloring | Manual iteration | Automatic coloring |
| Confidence intervals | Built-in | Manual calculation | Built-in |
| FacetGrid support | No (single axes) | No | Yes (automatic subplots) |
| Statistical estimation | Mean, median, etc. | None | Mean, median, etc. |
| Semantic mappings | hue, size, style | Manual | hue, size, style, col, row |
| Default styling | Seaborn theme | Matplotlib default | Seaborn theme |
| Legend handling | Automatic | Manual | Automatic |
| Code complexity | Low | Medium | Low |
| Performance (large data) | Medium | Fast | Medium |
| Customization depth | High (via ax) | Highest | Medium (FacetGrid limits) |
| Best use case | Single plot, grouped data | Simple plots, full control | Multi-facet comparisons |
Utilisez sns.lineplot() lorsque vous avez besoin d’une agrégation automatique et d’une visualisation statistique sur un seul graphique.
Utilisez plt.plot() lorsque vous avez besoin d’un contrôle maximal, de meilleures performances, ou que vous tracez des données déjà agrégées.
Utilisez sns.relplot(kind="line") lorsque vous avez besoin de graphiques facettés avec génération automatique de sous-graphiques.
Tableau de référence des paramètres
| Parameter | Type | Default | Description |
|---|---|---|---|
data | DataFrame, dict, array | None | Input data structure |
x, y | str, array | None | Variables for x and y axes |
hue | str | None | Grouping variable for color encoding |
size | str | None | Grouping variable for line width |
style | str | None | Grouping variable for line dash patterns |
palette | str, list, dict | None | Color palette for hue levels |
hue_order | list | None | Order for hue variable levels |
units | str | None | Grouping for sampling units (no aggregation) |
estimator | function | np.mean | Aggregation function (mean, median, etc.) |
errorbar | tuple, str | ('ci', 95) | Error representation method |
n_boot | int | 1000 | Bootstrap iterations for CI |
seed | int | None | Random seed for bootstrap |
sort | bool | True | Sort x variable before plotting |
err_style | str | 'band' | 'band' or 'bars' for error display |
err_kws | dict | None | Keyword args for error representation |
markers | bool, list | False | Marker styles for data points |
dashes | bool, list | True | Line dash patterns |
legend | str, bool | 'auto' | Legend display behavior |
ci | int, 'sd', None | Deprecated | Use errorbar instead |
ax | Axes | None | Matplotlib axes object |
linewidth | float | 1.5 | Width of line |
linestyle | str | '-' | Line style ('-', '--', '-.', ':') |
Exemple réel : analyse des cours boursiers
# Simulate stock price data
np.random.seed(42)
dates = pd.date_range('2024-01-01', periods=252, freq='B') # Business days
stocks_real = pd.DataFrame({
'Date': np.tile(dates, 4),
'Price': np.concatenate([
100 * np.exp(np.random.randn(252).cumsum() * 0.01), # AAPL
150 * np.exp(np.random.randn(252).cumsum() * 0.012), # GOOGL
200 * np.exp(np.random.randn(252).cumsum() * 0.011), # MSFT
80 * np.exp(np.random.randn(252).cumsum() * 0.015) # TSLA
]),
'Ticker': ['AAPL'] * 252 + ['GOOGL'] * 252 + ['MSFT'] * 252 + ['TSLA'] * 252
})
# Calculate normalized returns (base = 100)
stocks_normalized = stocks_real.copy()
for ticker in stocks_normalized['Ticker'].unique():
mask = stocks_normalized['Ticker'] == ticker
first_price = stocks_normalized.loc[mask, 'Price'].iloc[0]
stocks_normalized.loc[mask, 'Normalized_Return'] = (
stocks_normalized.loc[mask, 'Price'] / first_price * 100
)
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 10))
# Absolute prices
sns.lineplot(
data=stocks_real,
x='Date',
y='Price',
hue='Ticker',
palette='deep',
linewidth=2,
ax=ax1
)
ax1.set_title('Stock Prices - Absolute Values (2024)', fontsize=16, fontweight='bold')
ax1.set_xlabel('')
ax1.set_ylabel('Price ($)', fontsize=12)
ax1.legend(title='Ticker', title_fontsize=11, fontsize=10, loc='upper left')
ax1.grid(True, alpha=0.3)
# Normalized returns
sns.lineplot(
data=stocks_normalized,
x='Date',
y='Normalized_Return',
hue='Ticker',
palette='deep',
linewidth=2,
ax=ax2
)
ax2.axhline(y=100, color='gray', linestyle='--', linewidth=1, alpha=0.7)
ax2.set_title('Normalized Returns (Base = 100)', fontsize=16, fontweight='bold')
ax2.set_xlabel('Date', fontsize=12)
ax2.set_ylabel('Normalized Return', fontsize=12)
ax2.legend(title='Ticker', title_fontsize=11, fontsize=10, loc='upper left')
ax2.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()Exemple réel : supervision de données de capteurs
# IoT sensor data with noise
hours = np.linspace(0, 24, 288) # 5-minute intervals
sensor_data = pd.DataFrame({
'time': np.tile(hours, 4),
'temperature': np.concatenate([
20 + 5 * np.sin(hours * np.pi / 12) + np.random.randn(288) * 0.5, # Room 1
22 + 4 * np.sin(hours * np.pi / 12 - 0.5) + np.random.randn(288) * 0.7, # Room 2
19 + 6 * np.sin(hours * np.pi / 12 + 0.3) + np.random.randn(288) * 0.6, # Room 3
21 + 5.5 * np.sin(hours * np.pi / 12 - 0.2) + np.random.randn(288) * 0.8 # Room 4
]),
'room': ['Room_1'] * 288 + ['Room_2'] * 288 + ['Room_3'] * 288 + ['Room_4'] * 288,
'building': ['Building_A'] * 576 + ['Building_B'] * 576
})
fig, ax = plt.subplots(figsize=(14, 7))
sns.lineplot(
data=sensor_data,
x='time',
y='temperature',
hue='room',
style='building',
palette='tab10',
linewidth=2,
markers=False,
errorbar=('ci', 68), # 1 standard deviation
ax=ax
)
# Add comfort zone
ax.axhspan(18, 24, alpha=0.1, color='green', label='Comfort Zone')
ax.set_title('24-Hour Temperature Monitoring Across Rooms', fontsize=16, fontweight='bold')
ax.set_xlabel('Hour of Day', fontsize=12)
ax.set_ylabel('Temperature (°C)', fontsize=12)
ax.set_xticks(range(0, 25, 2))
ax.legend(title='Location', bbox_to_anchor=(1.05, 1), loc='upper left')
ax.grid(True, alpha=0.3, linestyle=':')
plt.tight_layout()
plt.show()Exemple réel : résultats d’un test A/B au fil du temps
# A/B test conversion rates over time
days = np.arange(1, 31)
ab_test = pd.DataFrame({
'day': np.tile(days, 2),
'conversion_rate': np.concatenate([
0.05 + 0.001 * days + np.random.randn(30) * 0.005, # Control
0.055 + 0.0012 * days + np.random.randn(30) * 0.005 # Variant
]) * 100,
'variant': ['Control'] * 30 + ['Variant_B'] * 30,
'sample_size': np.random.randint(800, 1200, 60)
})
fig, axes = plt.subplots(2, 1, figsize=(12, 9), sharex=True)
# Conversion rate trend
sns.lineplot(
data=ab_test,
x='day',
y='conversion_rate',
hue='variant',
palette={'Control': '#95a5a6', 'Variant_B': '#27ae60'},
linewidth=2.5,
markers=True,
markersize=6,
errorbar=None,
ax=axes[0]
)
axes[0].set_title('A/B Test: Conversion Rate Over Time', fontsize=16, fontweight='bold')
axes[0].set_ylabel('Conversion Rate (%)', fontsize=12)
axes[0].set_xlabel('')
axes[0].legend(title='Test Group', fontsize=11)
axes[0].grid(True, alpha=0.3)
# Sample size tracking
sns.lineplot(
data=ab_test,
x='day',
y='sample_size',
hue='variant',
palette={'Control': '#95a5a6', 'Variant_B': '#27ae60'},
linewidth=2,
markers=False,
errorbar=None,
ax=axes[1]
)
axes[1].set_title('Daily Sample Size', fontsize=14, fontweight='bold')
axes[1].set_ylabel('Users', fontsize=12)
axes[1].set_xlabel('Day of Test', fontsize=12)
axes[1].legend(title='Test Group', fontsize=11)
axes[1].grid(True, alpha=0.3)
plt.tight_layout()
plt.show()Enregistrer et exporter des graphiques en courbes
Enregistrez les graphiques dans différents formats pour des rapports et des présentations :
# Create a polished chart for export
fig, ax = plt.subplots(figsize=(10, 6), dpi=100)
export_data = pd.DataFrame({
'month': ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun'] * 2,
'revenue': [50, 55, 53, 60, 65, 70, 45, 48, 50, 55, 58, 63],
'region': ['North'] * 6 + ['South'] * 6
})
sns.lineplot(
data=export_data,
x='month',
y='revenue',
hue='region',
palette='Set1',
linewidth=3,
markers=True,
markersize=10,
ax=ax
)
ax.set_title('Regional Revenue Comparison', fontsize=16, fontweight='bold', pad=15)
ax.set_xlabel('Month', fontsize=13)
ax.set_ylabel('Revenue ($K)', fontsize=13)
ax.legend(title='Region', title_fontsize=12, fontsize=11)
ax.grid(True, alpha=0.4)
# Save in multiple formats
plt.savefig('revenue_comparison.png', dpi=300, bbox_inches='tight') # High-res PNG
plt.savefig('revenue_comparison.pdf', bbox_inches='tight') # Vector PDF
plt.savefig('revenue_comparison.svg', bbox_inches='tight') # SVG for web
# Save with transparent background
plt.savefig('revenue_comparison_transparent.png', dpi=300,
bbox_inches='tight', transparent=True)
plt.show()
print("Charts saved in multiple formats:")
print("- revenue_comparison.png (300 DPI)")
print("- revenue_comparison.pdf (vector)")
print("- revenue_comparison.svg (web)")
print("- revenue_comparison_transparent.png (transparent)")Enregistrer avec des dimensions spécifiques :
# Set exact figure size for publication
fig = plt.figure(figsize=(8, 5)) # Width, height in inches
ax = fig.add_subplot(111)
sns.lineplot(data=export_data, x='month', y='revenue', hue='region', ax=ax)
ax.set_title('Revenue Trends')
# Save with exact pixel dimensions (at 100 DPI: 8 inches * 100 = 800 pixels)
plt.savefig('chart_800x500.png', dpi=100, bbox_inches='tight')
# Save with higher resolution (8 inches * 300 DPI = 2400 pixels)
plt.savefig('chart_2400x1500.png', dpi=300, bbox_inches='tight')
plt.close()Graphiques en courbes interactifs avec PyGWalker
Pour l’exploration interactive des données de graphiques en courbes, pensez à PyGWalker, une bibliothèque Python open-source qui convertit les DataFrames en visualisations interactives de type Tableau :
# Install PyGWalker: pip install pygwalker
import pygwalker as pyg
import pandas as pd
import numpy as np
# Create time series data
dates = pd.date_range('2025-01-01', periods=365, freq='D')
interactive_data = pd.DataFrame({
'Date': dates,
'Sales': 1000 + np.random.randn(365).cumsum() * 50,
'Costs': 600 + np.random.randn(365).cumsum() * 30,
'Region': np.random.choice(['North', 'South', 'East', 'West'], 365),
'Product': np.random.choice(['Product_A', 'Product_B', 'Product_C'], 365)
})
# Launch interactive explorer
walker = pyg.walk(interactive_data)PyGWalker fournit :
- Une interface drag-and-drop pour créer des graphiques en courbes
- Du filtrage et du regroupement interactifs
- Une agrégation automatique et un binning des dates
- La comparaison multi-séries
- L’export vers des graphiques statiques
- Pas besoin de coder manuellement chaque visualisation
C’est particulièrement utile en analyse exploratoire (EDA) lorsque vous devez tester rapidement différents regroupements, plages temporelles et agrégations sans écrire du code pour chaque variante. Consultez github.com/Kanaries/pygwalker (opens in a new tab) pour l’installation et la documentation.
Conseils avancés et bonnes pratiques
Gérer les grands jeux de données
Pour des datasets avec des milliers de points par série, envisagez un downsampling ou une agrégation :
# Large dataset simulation
large_data = pd.DataFrame({
'timestamp': pd.date_range('2025-01-01', periods=10000, freq='T'),
'value': np.random.randn(10000).cumsum()
})
# Method 1: Downsample to hourly
hourly = large_data.set_index('timestamp').resample('H').mean().reset_index()
sns.lineplot(data=hourly, x='timestamp', y='value')
plt.title('Downsampled to Hourly Average')
plt.show()
# Method 2: Use estimator for automatic aggregation
large_data['hour'] = large_data['timestamp'].dt.floor('H')
sns.lineplot(data=large_data, x='hour', y='value', estimator='median')
plt.title('Median Aggregation by Hour')
plt.xticks(rotation=45)
plt.tight_layout()
plt.show()Combiner plusieurs estimateurs
Comparez différentes agrégations statistiques :
# Noisy experimental data
experiment_multi = pd.DataFrame({
'dose': [0.1, 0.5, 1.0, 2.0, 5.0] * 20,
'response': np.random.lognormal([1, 1.5, 2, 2.5, 3] * 20, 0.4)
})
fig, axes = plt.subplots(1, 3, figsize=(15, 4))
# Mean with CI
sns.lineplot(data=experiment_multi, x='dose', y='response',
estimator='mean', errorbar=('ci', 95), ax=axes[0])
axes[0].set_title('Mean ± 95% CI')
# Median with IQR
sns.lineplot(data=experiment_multi, x='dose', y='response',
estimator='median', errorbar=('pi', 50), ax=axes[1])
axes[1].set_title('Median ± IQR')
# Custom estimator (75th percentile)
sns.lineplot(data=experiment_multi, x='dose', y='response',
estimator=lambda x: np.percentile(x, 75), errorbar=None, ax=axes[2])
axes[2].set_title('75th Percentile')
plt.tight_layout()
plt.show()Mettre en évidence des zones spécifiques
Attirez l’attention sur des périodes importantes :
# Sales data with promotion period
sales_highlight = pd.DataFrame({
'week': range(1, 53),
'sales': 1000 + np.random.randn(52).cumsum() * 100 +
np.where((np.arange(52) >= 20) & (np.arange(52) <= 30), 500, 0)
})
fig, ax = plt.subplots(figsize=(12, 6))
sns.lineplot(data=sales_highlight, x='week', y='sales', linewidth=2.5, color='#3498db')
# Highlight promotion period
ax.axvspan(20, 30, alpha=0.2, color='gold', label='Promotion Period')
ax.axhline(y=sales_highlight['sales'].mean(), color='red',
linestyle='--', linewidth=1.5, alpha=0.7, label='Average Sales')
ax.set_title('Sales Performance with Promotion Period Highlighted',
fontsize=16, fontweight='bold')
ax.set_xlabel('Week', fontsize=12)
ax.set_ylabel('Sales ($)', fontsize=12)
ax.legend(fontsize=11)
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()FAQ
Conclusion
La fonction lineplot() de Seaborn fournit une interface puissante et accessible pour créer des graphiques en courbes de qualité publication. De la visualisation de tendances basique aux comparaisons complexes multi-séries avec agrégation statistique, elle prend en charge les tâches courantes de traçage avec un minimum de code tout en conservant une personnalisation complète via l’intégration à matplotlib.
La gestion automatique des intervalles de confiance, le mapping sémantique des couleurs et l’intégration native avec les DataFrames éliminent le code répétitif et vous permettent de vous concentrer sur les insights plutôt que sur la mécanique du plotting. Qu’il s’agisse de visualiser des tendances temporelles, de comparer des groupes expérimentaux ou de surveiller des métriques système, sns.lineplot() produit des visualisations propres et informatives qui communiquent efficacement.
Pour des graphiques statiques destinés à la publication, combinez l’interface haut niveau de seaborn avec le contrôle fin de matplotlib. Pour l’exploration interactive et le prototypage rapide, des outils comme PyGWalker étendent ces capacités via des interfaces drag-and-drop qui ne nécessitent pas de code pour chaque itération de visualisation.
Maîtrisez ces techniques pour transformer des données brutes en récits visuels clairs, qui aident à la prise de décision et à la communication d’insights auprès de publics techniques et non techniques.