🌊 Seaborn

从零开始的数据分析之旅

📖 Seaborn:统计可视化的艺术

Seaborn构建在Matplotlib之上,提供了更高级的统计图表接口。如果说Matplotlib是画笔,Seaborn就是模板——用更少的代码画出更漂亮的统计图表。默认配色、自动图例、智能布局,让你专注数据分析而非调样式。

Seaborn图表体系: 关系图(relational) 分布图(distribution) 分类图(categorical) ──────────────── ────────────────── ────────────────── scatterplot() histplot() stripplot() lineplot() kdeplot() swarmplot() ecdfplot() boxplot() 回归图(regression) ────────── violinplot() ──────────────── jointplot() boxenplot() regplot() pairplot() barplot() residplot() pointplot() 热力图 countplot() ──────── heatmap() 分面: clustermap() FacetGrid

1. 热力图(Heatmap)

热力图是展示相关矩阵、混淆矩阵等二维数据的首选:

import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

# 相关矩阵热力图
corr_data = pd.DataFrame(np.random.randn(100, 5), columns=list('ABCDE'))
corr = corr_data.corr()

fig, ax = plt.subplots(figsize=(8, 6))
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0,
            square=True, linewidths=0.5, ax=ax)

🎻 小提琴图与箱线图

小提琴图(Violin Plot)

小提琴图 = 箱线图 + 核密度估计,既展示统计摘要又展示分布形状:

# 加载示例数据
tips = sns.load_dataset('tips')

# 小提琴图
sns.violinplot(data=tips, x='day', y='total_bill', 
               hue='sex', split=True, palette='coolwarm')

箱线图+散点叠加

# 箱线图看概要,散点看细节
sns.boxplot(data=tips, x='day', y='total_bill', color='#1a1a2e')
sns.stripplot(data=tips, x='day', y='total_bill', 
              color='#3b82f6', alpha=0.5, size=4)
小提琴图的宽度表示数据密度,越宽的地方数据越集中。split=True时左右分别显示hue的不同类别。

🖼️ 分面图(FacetGrid)

分面图是Seaborn最强大的功能之一——按类别自动创建子图网格:

# 按时间和性别分面
g = sns.FacetGrid(tips, col='time', row='sex', height=3, aspect=1.2)
g.map(sns.histplot, 'total_bill', bins=15, color='#3b82f6')

# pairplot: 所有变量的两两关系
iris = sns.load_dataset('iris')
g2 = sns.pairplot(iris, hue='species', height=2, palette='coolwarm')
分面类型函数用途
FacetGridsns.FacetGrid()按行列变量分面
PairGridsns.pairplot()变量两两关系
JointGridsns.jointplot()双变量+边缘分布

📐 2024-2025 Seaborn前沿

📊 分布图详解

# histplot: 直方图+KDE
sns.histplot(data=tips, x='total_bill', bins=30,
             kde=True, color='#3b82f6', alpha=0.6)

# KDE图
sns.kdeplot(data=tips, x='total_bill', hue='time',
            fill=True, alpha=0.3, palette='coolwarm')

# ECDF(经验累积分布)
sns.ecdfplot(data=tips, x='total_bill', hue='time',
             palette='coolwarm')

# jointplot: 散点+边缘分布
sns.jointplot(data=tips, x='total_bill', y='tip',
              hue='time', palette='coolwarm', height=8)

🎨 Seaborn样式定制

# 五种主题
sns.set_theme(style='darkgrid')  # darkgrid/whitegrid/dark/white/ticks

# 上下文(字体大小)
sns.set_context('notebook')  # paper/notebook/talk/poster

# 自定义调色板
custom = ['#3b82f6', '#60a5fa', '#93c5fd', '#bfdbfe']
sns.set_palette(custom)
with sns.axes_style('darkgrid'):只改变单个图表的样式。

💻 完整实战代码

#!/usr/bin/env python3
# Seaborn — 完整实战

import matplotlib
matplotlib.use('Agg')
import seaborn as sns
import matplotlib.pyplot as plt
import numpy as np
import pandas as pd

plt.style.use('dark_background')
sns.set_theme(style='darkgrid')

# ============ 内置数据 ============
tips = sns.load_dataset('tips')
print(f"tips数据: {tips.shape}")
print(tips.head())

# ============ 热力图 ============
corr_data = pd.DataFrame(np.random.randn(100, 5), columns=list('ABCDE'))
corr = corr_data.corr()
fig, ax = plt.subplots(figsize=(8, 6))
sns.heatmap(corr, annot=True, fmt='.2f', cmap='coolwarm', center=0,
            square=True, linewidths=0.5, ax=ax)
ax.set_title('热力图: 相关矩阵')
plt.savefig('heatmap.png', dpi=100, bbox_inches='tight')
print("热力图已保存")

# ============ 小提琴图 ============
fig, ax = plt.subplots(figsize=(8, 5))
sns.violinplot(data=tips, x='day', y='total_bill', hue='sex',
               split=True, ax=ax, palette=['#3b82f6', '#60a5fa'])
ax.set_title('小提琴图: 每日账单分布')
plt.savefig('violin.png', dpi=100, bbox_inches='tight')
print("小提琴图已保存")

# ============ 分面图 ============
g = sns.FacetGrid(tips, col='time', row='sex', height=3, aspect=1.2)
g.map(sns.histplot, 'total_bill', bins=15, color='#3b82f6')
g.savefig('facet.png', dpi=100)
print("分面图已保存")

# ============ pairplot ============
iris = sns.load_dataset('iris')
g2 = sns.pairplot(iris, hue='species', height=2, palette='coolwarm')
g2.savefig('pairplot.png', dpi=100)
print("pairplot已保存")

# ============ 箱线图+散点 ============
fig, ax = plt.subplots(figsize=(8, 5))
sns.boxplot(data=tips, x='day', y='total_bill', ax=ax, color='#1a1a2e')
sns.stripplot(data=tips, x='day', y='total_bill', ax=ax, color='#3b82f6', alpha=0.5, size=4)
ax.set_title('箱线图+散点')
plt.savefig('box.png', dpi=100, bbox_inches='tight')
print("箱线图已保存")

print("\n✅ Python验证通过 — 热力图/小提琴图/分面")
🏆 成就解锁:热力图/小提琴图/分面
Python验证通过 — 热力图(5×5相关矩阵带标注)、小提琴图(按日+性别分面)、FacetGrid(time×sex网格)、pairplot(鸢尾花4特征×3类)、箱线图+散点叠加全部成功生成。
思考题:
① 小提琴图和箱线图各有什么优缺点?
② heatmap的center参数有什么用?
③ FacetGrid的map和map_dataframe有什么区别?
④ pairplot适合多少维度的数据?

📝 课后练习

  1. 用Seaborn绘制5种不同类型的统计图表
  2. 实现一个自定义的FacetGrid分析
  3. 用jointplot展示两个变量的联合分布和边缘分布
  4. 对比Seaborn和Matplotlib在相同图表上的代码量
  5. 用seaborn.objects接口重绘一个图表
📚 参考资料:
• Seaborn官方文档: seaborn.pydata.org
• Seaborn Gallery: seaborn.pydata.org/examples
• Python Data Science Handbook (Jake VanderPlas)
• Seaborn Objects API: seaborn.pydata.org/tutorial/objects_interface

🗺️ Seaborn图表选择指南

Seaborn图表选择决策树: 分析目标? ├ 看关系 → relational │ ├ 两个连续变量 → scatterplot │ ├ 趋势+置信区间 → regplot/lmplot │ └ 时间序列 → lineplot ├ 看分布 → distribution │ ├ 单变量 → histplot + kde │ ├ 双变量 → jointplot │ ├ 多变量两两 → pairplot │ └ 累积分布 → ecdfplot ├ 看分类 → categorical │ ├ 中心+离散 → boxplot │ ├ 分布形状 → violinplot │ ├ 每个数据点 → swarmplot/stripplot │ ├ 均值比较 → barplot/pointplot │ └ 计数 → countplot └ 看矩阵 → matrix ├ 相关矩阵 → heatmap └ 聚类 → clustermap

Seaborn vs Matplotlib对比

特性MatplotlibSeaborn
定位底层绘图统计可视化
代码量多(手动调参)少(智能默认)
美观度需自定义默认漂亮
统计功能内置(KDE/CI/回归)
灵活性极高中等
学习曲线陡峭平缓
推荐用法精细定制快速探索

🔑 本课关键要点

Seaborn核心5条:
① Seaborn = Matplotlib + 统计智能默认值
② 三大图表类别:关系图、分布图、分类图
③ 热力图展示相关矩阵,小提琴图展示分布形状
④ FacetGrid自动分面——按类别创建子图网格
set_theme(style='darkgrid')一键美化
# Seaborn速查
# 分布
sns.histplot(data, x='列', kde=True)
sns.kdeplot(data, x='列', hue='组')

# 关系
sns.scatterplot(data, x='列1', y='列2', hue='组')
sns.regplot(data, x='列1', y='列2')

# 分类
sns.boxplot(data, x='分类', y='值')
sns.violinplot(data, x='分类', y='值', hue='组', split=True)
sns.barplot(data, x='分类', y='值')

# 矩阵
sns.heatmap(corr, annot=True, cmap='coolwarm', center=0)

# 分面
g = sns.FacetGrid(data, col='列1', row='列2')
g.map(sns.histplot, '值')
Seaborn性能优化:①大数据量(>10万)用scatterplotswarmplot快很多 ②用throttle参数控制渲染密度 ③pairplot对高维数据很慢,先选子集 ④用sample先画子集预览。