从零开始的数据分析之旅
Seaborn构建在Matplotlib之上,提供了更高级的统计图表接口。如果说Matplotlib是画笔,Seaborn就是模板——用更少的代码画出更漂亮的统计图表。默认配色、自动图例、智能布局,让你专注数据分析而非调样式。
热力图是展示相关矩阵、混淆矩阵等二维数据的首选:
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)
小提琴图 = 箱线图 + 核密度估计,既展示统计摘要又展示分布形状:
# 加载示例数据
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)
分面图是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')
| 分面类型 | 函数 | 用途 |
|---|---|---|
| FacetGrid | sns.FacetGrid() | 按行列变量分面 |
| PairGrid | sns.pairplot() | 变量两两关系 |
| JointGrid | sns.jointplot() | 双变量+边缘分布 |
# 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)
# 五种主题
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验证通过 — 热力图/小提琴图/分面")
| 特性 | Matplotlib | Seaborn |
|---|---|---|
| 定位 | 底层绘图 | 统计可视化 |
| 代码量 | 多(手动调参) | 少(智能默认) |
| 美观度 | 需自定义 | 默认漂亮 |
| 统计功能 | 无 | 内置(KDE/CI/回归) |
| 灵活性 | 极高 | 中等 |
| 学习曲线 | 陡峭 | 平缓 |
| 推荐用法 | 精细定制 | 快速探索 |
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, '值')
scatterplot比swarmplot快很多 ②用throttle参数控制渲染密度 ③pairplot对高维数据很慢,先选子集 ④用sample先画子集预览。