Seaborn
Tutorial Completo di Seaborn con Esempi
Seaborn è una libreria di visualizzazione dati Python basata su Matplotlib. Fornisce un'interfaccia di alto livello per creare visualizzazioni statistiche attraenti e informative.
Indice
Installazione e Importazione
Configurazione e Stili
Tipi di Grafici
Relational Plots
Categorical Plots
Distribution Plots
Regression Plots
Matrix Plots
Personalizzazione
Temi e Contesti
Esempi Pratici
Integrazione con Pandas
Risorse Utili
Documentazione Ufficiale: https://seaborn.pydata.org/
Galleria Esempi: https://seaborn.pydata.org/examples/index.html
Tutorial: https://seaborn.pydata.org/tutorial.html
Color Palettes: https://seaborn.pydata.org/tutorial/color_palettes.html
1. Installazione e Importazione
Installazione
pip install seaborn
# oppure
conda install seaborn
Importazione
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd
# Per i notebook Jupyter
%matplotlib inline
2. Configurazione e Stili
# Impostare lo stile di Seaborn
sns.set_theme(style="whitegrid") # whitegrid, darkgrid, white, dark, ticks
# Caricare dataset di esempio
tips = sns.load_dataset("tips")
iris = sns.load_dataset("iris")
titanic = sns.load_dataset("titanic")
flights = sns.load_dataset("flights")
# Visualizzare i primi dati
print(tips.head())
3. Tipi di Grafici
Relational Plots (relplot)
# Scatter plot con relplot
sns.relplot(
data=tips,
x="total_bill",
y="tip",
hue="smoker", # Colore per categoria
style="time", # Stile per categoria
size="size", # Dimensione punti
sizes=(40, 200), # Range dimensioni
alpha=0.7
)
plt.title("Relazione tra Conto e Mancia")
plt.show()
# Line plot con relplot
sns.relplot(
data=flights,
x="year",
y="passengers",
kind="line", # Tipo line plot
hue="month",
style="month",
markers=True,
dashes=False
)
plt.title("Passeggeri per Anno e Mese")
plt.xticks(rotation=45)
plt.show()
Categorical Plots (catplot)
# Box plot
sns.catplot(
data=tips,
x="day",
y="total_bill",
hue="sex",
kind="box",
height=6,
aspect=1.5
)
plt.title("Distribuzione Conto per Giorno e Sesso")
plt.show()
# Violin plot
sns.catplot(
data=tips,
x="day",
y="total_bill",
hue="sex",
kind="violin",
split=True, # Dividi i violini
height=6,
aspect=1.5
)
plt.title("Distribuzione Conto (Violin Plot)")
plt.show()
# Bar plot
sns.catplot(
data=tips,
x="day",
y="total_bill",
hue="sex",
kind="bar",
ci="sd", # Deviazione standard invece di intervallo confidenza
height=6,
aspect=1.5
)
plt.title("Conto Medio per Giorno e Sesso")
plt.show()
# Count plot
sns.catplot(
data=tips,
x="day",
hue="sex",
kind="count",
height=6,
aspect=1.5
)
plt.title("Conteggio Pasti per Giorno e Sesso")
plt.show()
Distribution Plots
# Histogram con KDE
sns.histplot(
data=tips,
x="total_bill",
hue="sex",
element="step", # step, bars, poly
stat="density", # count, frequency, density, probability
common_norm=False, # Normalizza separatamente
kde=True # Aggiungi Kernel Density Estimate
)
plt.title("Distribuzione del Conto per Sesso")
plt.show()
# KDE plot
sns.kdeplot(
data=tips,
x="total_bill",
hue="sex",
fill=True,
alpha=0.5,
common_norm=False
)
plt.title("Densità del Conto per Sesso")
plt.show()
# Joint plot (scatter + histogram)
g = sns.jointplot(
data=tips,
x="total_bill",
y="tip",
hue="smoker",
kind="scatter", # scatter, reg, resid, kde, hex
marginal_kws=dict(bins=25, fill=True)
)
g.fig.suptitle("Relazione Conto-Mancia con Distribuzioni Marginali")
plt.tight_layout()
plt.show()
# Pair plot (matrice di scatter plots)
g = sns.pairplot(
iris,
hue="species",
palette="viridis",
diag_kind="hist", # hist, kde, None
corner=False # True per triangolo inferiore
)
g.fig.suptitle("Pair Plot del Dataset Iris")
plt.tight_layout()
plt.show()
Regression Plots (lmplot)
# Linear regression plot
sns.lmplot(
data=tips,
x="total_bill",
y="tip",
hue="smoker",
col="time", # Facet per colonne
row="sex", # Facet per righe
height=4,
aspect=1.2,
ci=95 # Intervallo di confidenza
)
plt.suptitle("Regressione Lineare: Conto vs Mancia")
plt.tight_layout()
plt.show()
# Regressione polinomiale
sns.lmplot(
data=tips,
x="total_bill",
y="tip",
order=2, # Grado polinomiale
scatter_kws={"alpha": 0.5},
line_kws={"color": "red"}
)
plt.title("Regressione Polinomiale (Grado 2)")
plt.show()
# Robust regression (resistente agli outliers)
sns.lmplot(
data=tips,
x="total_bill",
y="tip",
robust=True,
ci=None
)
plt.title("Regressione Robusta")
plt.show()
Matrix Plots
# Heatmap
# Preparare i dati
flights_pivot = flights.pivot("month", "year", "passengers")
plt.figure(figsize=(10, 8))
sns.heatmap(
flights_pivot,
annot=True, # Mostra valori
fmt="d", # Formato interi
cmap="YlOrRd", # Colormap
linewidths=0.5,
cbar_kws={"label": "Passeggeri"}
)
plt.title("Heatmap: Passeggeri per Mese e Anno")
plt.tight_layout()
plt.show()
# Cluster map
iris_numeric = iris.drop("species", axis=1)
g = sns.clustermap(
iris_numeric,
standard_scale=1, # Normalizza per righe (1) o colonne (0)
cmap="viridis",
figsize=(8, 8)
)
plt.suptitle("Cluster Map del Dataset Iris")
plt.show()
# Correlation heatmap
corr = tips.corr(numeric_only=True)
mask = np.triu(np.ones_like(corr, dtype=bool)) # Maschera triangolo superiore
plt.figure(figsize=(8, 6))
sns.heatmap(
corr,
mask=mask,
annot=True,
cmap="coolwarm",
center=0,
square=True,
linewidths=0.5
)
plt.title("Matrice di Correlazione")
plt.tight_layout()
plt.show()
4. Personalizzazione
# Personalizzazione avanzata
plt.figure(figsize=(10, 6))
ax = sns.barplot(
data=tips,
x="day",
y="total_bill",
hue="sex",
palette="Set2", # Palette colori
saturation=0.8, # Saturazione colori
errcolor=".2", # Colore error bars
errwidth=1.5, # Spessore error bars
capsize=0.1 # Dimensione caps
)
# Personalizzare ulteriormente con matplotlib
plt.title("Conto Medio per Giorno e Sesso", fontsize=16, fontweight="bold")
plt.xlabel("Giorno", fontsize=12)
plt.ylabel("Conto Medio ($)", fontsize=12)
plt.legend(title="Sesso", title_fontsize=12, fontsize=11)
# Aggiungere valori sulle barre
for container in ax.containers:
ax.bar_label(container, fmt='%.1f', padding=3)
plt.tight_layout()
plt.show()
5. Temi e Contesti
# Cambiare tema e contesto
themes = ["whitegrid", "darkgrid", "white", "dark", "ticks"]
contexts = ["paper", "notebook", "talk", "poster"]
for i, theme in enumerate(themes, 1):
plt.figure(figsize=(6, 4))
sns.set_theme(style=theme)
sns.histplot(data=tips, x="total_bill", kde=True)
plt.title(f"Tema: {theme}")
plt.tight_layout()
plt.show()
# Ripristinare tema predefinito
sns.set_theme(style="whitegrid")
# Cambiare contesto (dimensione elementi)
sns.set_context("paper") # Elementi più piccoli
sns.histplot(data=tips, x="total_bill", kde=True)
plt.title("Contesto: Paper")
plt.show()
sns.set_context("poster") # Elementi più grandi
sns.histplot(data=tips, x="total_bill", kde=True)
plt.title("Contesto: Poster")
plt.show()
# Ripristinare contesto predefinito
sns.set_context("notebook")
6. Esempi Pratici
Analisi Dataset Titanic
# Analisi esplorativa Titanic
plt.figure(figsize=(12, 10))
# Sopravvivenza per classe e sesso
plt.subplot(2, 2, 1)
sns.barplot(data=titanic, x="class", y="survived", hue="sex", ci=None)
plt.title("Tasso di Sopravvivenza per Classe e Sesso")
plt.ylabel("Tasso di Sopravvivenza")
# Distribuzione età per sopravvivenza e sesso
plt.subplot(2, 2, 2)
sns.histplot(data=titanic, x="age", hue="survived", element="step",
stat="density", common_norm=False, kde=True)
plt.title("Distribuzione Età per Sopravvivenza")
plt.xlabel("Età")
# Sopravvivenza per porto di imbarco
plt.subplot(2, 2, 3)
sns.countplot(data=titanic, x="embarked", hue="survived")
plt.title("Sopravvivenza per Porto di Imbarco")
plt.xlabel("Porto di Imbarco")
# Distribuzione tariffe per classe
plt.subplot(2, 2, 4)
sns.boxplot(data=titanic, x="class", y="fare")
plt.title("Distribuzione Tariffe per Classe")
plt.yscale("log") # Scala logaritmica per meglio visualizzare outliers
plt.tight_layout()
plt.show()
Multiplot con FacetGrid
# Creare una griglia di subplots
g = sns.FacetGrid(tips, col="time", row="smoker", height=4, aspect=1.2)
g.map_dataframe(sns.scatterplot, x="total_bill", y="tip", hue="sex", alpha=0.7)
g.add_legend()
g.fig.suptitle("Relazione Conto-Mancia per Time e Smoker", y=1.02)
plt.tight_layout()
plt.show()
# Usare PairGrid per personalizzazione avanzata
g = sns.PairGrid(iris, hue="species", palette="viridis")
g.map_upper(sns.scatterplot, alpha=0.8) # Triangolo superiore: scatter
g.map_lower(sns.kdeplot, fill=True) # Triangolo inferiore: KDE
g.map_diag(sns.histplot, kde=True) # Diagonale: histogram con KDE
g.add_legend()
g.fig.suptitle("PairGrid Personalizzato per Dataset Iris", y=1.02)
plt.tight_layout()
plt.show()
7. Integrazione con Pandas
# Creare dataset di esempio
np.random.seed(42)
dates = pd.date_range('2023-01-01', '2023-12-31', freq='D')
df = pd.DataFrame({
'date': dates,
'sales': np.random.normal(1000, 200, len(dates)),
'temperature': np.random.normal(20, 5, len(dates)),
'region': np.random.choice(['North', 'South', 'East', 'West'], len(dates)),
'product': np.random.choice(['A', 'B', 'C'], len(dates))
})
# Aggiungere stagionalità
df['sales'] = df['sales'] + 100 * np.sin(2 * np.pi * df.date.dt.dayofyear / 365)
# Aggiungere giorno della settimana e mese
df['day_of_week'] = df['date'].dt.day_name()
df['month'] = df['date'].dt.month_name()
# Analisi vendite con Seaborn e Pandas
plt.figure(figsize=(15, 10))
# Andamento vendite nel tempo
plt.subplot(2, 2, 1)
df_weekly = df.resample('W', on='date')['sales'].mean().reset_index()
sns.lineplot(data=df_weekly, x='date', y='sales')
plt.title('Vendite Medie Settimanali')
plt.xticks(rotation=45)
# Vendite per regione e prodotto
plt.subplot(2, 2, 2)
sns.barplot(data=df, x='region', y='sales', hue='product', ci=None)
plt.title('Vendite per Regione e Prodotto')
# Distribuzione vendite per giorno della settimana
plt.subplot(2, 2, 3)
day_order = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
sns.boxplot(data=df, x='day_of_week', y='sales', order=day_order)
plt.title('Distribuzione Vendite per Giorno della Settimana')
plt.xticks(rotation=45)
# Correlazione tra temperatura e vendite
plt.subplot(2, 2, 4)
sns.scatterplot(data=df, x='temperature', y='sales', hue='region', alpha=0.6)
plt.title('Correlazione: Temperatura vs Vendite')
plt.tight_layout()
plt.show()
Dashboard Completa
# Creare una dashboard completa
fig = plt.figure(figsize=(18, 12))
# Definire la griglia
gs = fig.add_gridspec(3, 3)
# Heatmap correlazione
ax1 = fig.add_subplot(gs[0, 0])
numeric_df = df[['sales', 'temperature']].corr(numeric_only=True)
sns.heatmap(numeric_df, annot=True, cmap='coolwarm', center=0, ax=ax1)
ax1.set_title('Matrice di Correlazione')
# Distribuzione vendite
ax2 = fig.add_subplot(gs[0, 1])
sns.histplot(data=df, x='sales', kde=True, ax=ax2)
ax2.set_title('Distribuzione Vendite')
# Vendite per mese
ax3 = fig.add_subplot(gs[0, 2])
month_order = ['January', 'February', 'March', 'April', 'May', 'June',
'July', 'August', 'September', 'October', 'November', 'December']
monthly_sales = df.groupby('month')['sales'].mean().reindex(month_order)
sns.barplot(x=monthly_sales.index, y=monthly_sales.values, ax=ax3)
ax3.set_title('Vendite Medie per Mese')
ax3.tick_params(axis='x', rotation=45)
# Andamento temporale
ax4 = fig.add_subplot(gs[1, :])
df_daily = df.resample('D', on='date')['sales'].mean().reset_index()
sns.lineplot(data=df_daily, x='date', y='sales', ax=ax4)
ax4.set_title('Andamento Vendite Giornaliere')
ax4.tick_params(axis='x', rotation=45)
# Violin plot per regione
ax5 = fig.add_subplot(gs[2, 0])
sns.violinplot(data=df, x='region', y='sales', ax=ax5)
ax5.set_title('Distribuzione Vendite per Regione')
# Box plot per prodotto
ax6 = fig.add_subplot(gs[2, 1])
sns.boxplot(data=df, x='product', y='sales', ax=ax6)
ax6.set_title('Distribuzione Vendite per Prodotto')
# Scatter plot temperatura vs vendite
ax7 = fig.add_subplot(gs[2, 2])
sns.scatterplot(data=df, x='temperature', y='sales', hue='region', alpha=0.6, ax=ax7)
ax7.set_title('Temperatura vs Vendite')
plt.tight_layout()
plt.suptitle('Dashboard Analisi Vendite Completa', fontsize=16, fontweight='bold', y=0.98)
plt.show()
Last updated