Seaborn 统计绘图:基于 Pandas 的高级可视化
Seaborn 统计绘图:基于 Pandas 的高级可视化
教程简介
Seaborn 是建立在 Matplotlib 之上的 Python 数据可视化库,专为统计绘图而设计。它与 Pandas 数据结构深度集成,能够用极少的代码生成美观且信息丰富的图表。本教程将带你从基础到进阶,掌握如何用 Seaborn 快速将 DataFrame 转化为有洞察力的可视化作品。
环境配置与数据准备
开始前,请确保已安装所需库:
pip install pandas matplotlib seaborn
Seaborn 内置多个示例数据集,非常适合教学。我们主要使用经典的 tips(餐厅小费数据)和 penguins(企鹅体征数据)。
import seaborn as sns
import pandas as pd
import matplotlib.pyplot as plt
# 设置全局绘图风格与字体(支持中文)
plt.rcParams['font.sans-serif'] = ['SimHei'] # 用于显示中文
plt.rcParams['axes.unicode_minus'] = False # 解决负号显示问题
sns.set_style("whitegrid") # 设置背景样式
# 加载数据
tips = sns.load_dataset("tips")
penguins = sns.load_dataset("penguins").dropna()
一、Seaborn 绘图通用结构
Seaborn 函数主要分为两类:
- 轴级函数:返回 Matplotlib 的 Axes 对象,可用
plt.subplots组合,如sns.scatterplot、sns.histplot。 - 图级函数:返回 FacetGrid 或 JointGrid 等专门网格对象,管理一个或多个子图,如
sns.relplot、sns.displot、sns.catplot。
图级函数通过 col、row 参数直接实现分组分面,更适合快速探索数据。
二、关系型图(relational plots)
关系型图用于显示两个变量之间的统计关系,函数名以 relplot 和 scatterplot、lineplot 为主。
2.1 散点图与气泡图
# 基础散点图,用 hue 分类着色
sns.scatterplot(data=tips, x="total_bill", y="tip", hue="time")
plt.title("消费金额与小费关系")
plt.show()
# 图级版本,支持分面
sns.relplot(data=tips, x="total_bill", y="tip",
hue="smoker", size="size", # size 映射气泡大小
col="time", # 按用餐时间分面
kind="scatter", height=4)
plt.show()
2.2 折线图与置信区间
Seaborn 的折线图会自动计算均值和置信区间(默认95%),非常适合显示趋势。
# 按时间分组,显示小费平均值的日变化
sns.lineplot(data=tips, x="day", y="tip", hue="sex",
marker="o", err_style="bars")
plt.title("不同性别顾客每日平均小费")
plt.show()
三、分布图(distribution plots)
分布图用于观察单个变量或双变量的分布形态,核心函数包括 histplot、kdeplot、ecdfplot 以及图级接口 displot。
3.1 直方图与核密度估计
# 单个变量的直方图叠加密度曲线
sns.histplot(tips["total_bill"], bins=20, stat="density", kde=True, color="steelblue")
plt.title("消费总额分布")
plt.show()
# 双变量核密度图(等高线或填充)
sns.kdeplot(data=tips, x="total_bill", y="tip", fill=True, thresh=0.1, cmap="Blues")
plt.title("消费总额与小费的联合密度分布")
plt.show()
3.2 高级分面分布
图级 displot 可以通过 col 参数同时展示不同子集的分布。
sns.displot(data=tips, x="total_bill", col="time", kde=True, bins=20, height=4)
plt.show()
四、分类图(categorical plots)
Seaborn 的分类图专门处理定类变量与数值变量之间的关系,分为三类:散点式(stripplot、swarmplot)、分布式(boxplot、violinplot)和统计估计式(barplot、pointplot)。图级接口 catplot 可以统一调用它们。
4.1 箱线图与小提琴图
# 小提琴图结合箱线图,展示更丰富的分布信息
sns.violinplot(data=tips, x="day", y="total_bill",
hue="sex", split=True, inner="quart") # split 将男女并排
plt.title("不同日期的消费分布(按性别分割)")
plt.show()
# 增强的箱线图
sns.boxenplot(data=tips, x="day", y="total_bill", hue="smoker")
plt.title("增强箱线图(Letter-Value Plot)")
plt.show()
4.2 条形图与点估计图
条形图默认显示平均值和置信区间,适合比较类别间的中心趋势。
sns.barplot(data=tips, x="day", y="total_bill", hue="sex",
palette="Set2", errwidth=1.5, capsize=0.1)
plt.title("按日期和性别分组的平均消费")
plt.show()
# 点估计图(连线强调趋势)
sns.pointplot(data=tips, x="day", y="total_bill", hue="smoker",
dodge=True, markers=["o","s"], linestyles=["-","--"])
plt.title("点估计图:吸烟与非吸烟顾客的消费趋势")
plt.show()
4.3 分类散点图
在数据点较少时,直接用散点呈现更真实,避免箱线图的概括偏差。
# 带抖动的散点,叠加箱线图
sns.catplot(data=tips, x="day", y="total_bill", hue="time",
kind="strip", jitter=True, alpha=0.6)
plt.title("抖动散点图")
plt.show()
# swarmplot 无重叠,但数据量大时较慢
sns.swarmplot(data=tips, x="day", y="total_bill", hue="time", dodge=True, size=4)
plt.legend(loc='upper right')
plt.title("蜜蜂群图")
plt.show()
五、回归图(regression plots)
lmplot 和 regplot 可以在散点的基础上拟合并绘制线性回归模型及其置信区间。
5.1 线性回归拟合
# 基础回归线
sns.regplot(data=tips, x="total_bill", y="tip", scatter_kws={'alpha':0.5})
plt.title("消费金额与小费的线性回归")
plt.show()
# 分面回归,不同用餐时间画不同的子图
sns.lmplot(data=tips, x="total_bill", y="tip", col="time", hue="smoker",
height=4, truncate=False)
plt.show()
5.2 多项式与稳健回归
通过 order 参数拟合多项式,通过 robust=True 降低异常值影响。
sns.regplot(data=tips, x="total_bill", y="tip", order=2,
scatter_kws={'color':'grey','alpha':0.4}, line_kws={'color':'crimson'})
plt.title("二次多项式回归")
plt.show()
六、矩阵图与聚类热力图
6.1 热力图
热力图常用于展示矩阵数据,比如相关系数矩阵。
# 计算企鹅数据特征间的相关系数(选择数值列)
num_penguins = penguins.select_dtypes(include='number')
corr_matrix = num_penguins.corr()
sns.heatmap(corr_matrix, annot=True, cmap="coolwarm", center=0,
linewidths=0.5, square=True)
plt.title("企鹅体征相关系数矩阵")
plt.show()
6.2 聚类热力图
利用 clustermap 在热力图基础上加入行列聚类树状图。
# 标准化后再聚类,避免量纲影响
sns.clustermap(num_penguins, standard_scale=1, cmap="vlag",
row_cluster=True, col_cluster=True, figsize=(7,6))
plt.show()
七、多变量网格与Pairplot
pairplot 可一键生成所有数值变量的两两关系图,是探索性数据分析的利器。
# 按企鹅种类着色,对角线上显示密度图
sns.pairplot(penguins, hue="species", diag_kind="kde",
palette="Dark2", plot_kws={'alpha':0.7})
plt.show()
若要更细粒度控制,可使用 PairGrid。
g = sns.PairGrid(penguins, hue="species", corner=True) # 只显示下三角
g.map_lower(sns.scatterplot, s=15, alpha=0.6)
g.map_diag(sns.kdeplot)
g.add_legend()
plt.show()
八、主题控制与导出
Seaborn 提供了五种预设主题:darkgrid、whitegrid、dark、white、ticks。结合 Matplotlib,可全面控制图表的呈现。
# 切换主题
sns.set_style("ticks")
sns.set_context("talk") # 放大字体和线条,适合演讲
# 绘制图表
sns.boxplot(data=tips, x="day", y="total_bill", palette="pastel")
sns.despine() # 移除上边框和右边框
plt.title("干净风格箱线图")
plt.savefig("seaborn_boxplot.png", dpi=150, bbox_inches='tight')
plt.show()
九、实战:企鹅数据集分类探索
下面将以上知识串联,对企鹅数据集进行一次完整的多维度可视化探索。
# 设置全局上下文
sns.set_style("whitegrid")
sns.set_context("notebook")
# 1. 数值特征分布(分组小提琴图)
fig, axes = plt.subplots(1, 3, figsize=(15,4))
for ax, col in zip(axes, ['bill_length_mm', 'bill_depth_mm', 'flipper_length_mm']):
sns.violinplot(data=penguins, x='species', y=col, palette='Set2', ax=ax)
plt.tight_layout()
plt.show()
# 2. 物种与岛屿的交叉计数
sns.catplot(data=penguins, x="island", col="species", kind="count",
palette="Paired", height=3, aspect=1.2)
plt.show()
# 3. 体重与脚蹼长度的关系,按物种回归
sns.lmplot(data=penguins, x="flipper_length_mm", y="body_mass_g",
hue="species", aspect=1.5, height=5, scatter_kws={"s": 40, "alpha":0.7})
plt.title("企鹅:脚蹼长度与体重的物种差异")
plt.show()
十、进阶建议与最佳实践
- 数据预处理:Seaborn 假设输入为整洁的 DataFrame,务必先用 Pandas 清洗缺失值、转换数据类型。
- 性能优化:大数据集时不建议使用
swarmplot(计算密集),改用stripplot+ 适度抖动。 - 图表组合:使用
plt.subplots创建多个轴,再分别绘制轴级函数,实现自定义布局。 - 可解释性:合理利用
hue、size、style等参数编码额外维度,但避免过度复杂化。 - 色彩选择:保持语义一致,使用色盲友好调色板(如
colorblind、Set2),通过palette参数设置。 - 英文环境:若使用内置数据集,列名和类别多为英文,绘图时可通过字典替换为中文标签。
总结
通过本教程,你已经掌握了 Seaborn 统计绘图的核心技能:从单变量分布到多变量关系,从分类比较到回归分析,再到高级的分面网格与热力图。Seaborn 的价值在于它将统计可视化抽象为富有语义的函数,使得数据探索过程即代码书写过程。继续练习,你将能快速为数据分析报告或机器学习流程提供富有洞察力的视觉支持。