目录

一、什么是 Seaborn

1. Seaborn 基本概念

2. 为什么基于 Matplotlib 构建

二、单变量数据可视化

1. 直方图

2. 核密度估计图

3. 计数图

三、双变量数据可视化

1. 散点图

2. 统计柱状图

3. 箱线图

4. 小提琴图

5. 六边形蜂巢图

6. 二维核密度估计图

四、PairPlot

1. PairPlot 图表结构

2. 方法签名与代码示例

五、多变量

1. 核心视觉通道

2. 代码示例

六、Seaborn Style

1. 预设背景主题

2. 代码示例

总结


关于本篇代码中数据集来源的说明

本篇示例代码中用到的 tips(小费数据集)、penguins(企鹅数据集)、diamonds(钻石数据集)等,均为 Seaborn 内置的官方统计示例数据集

在代码中通过 sns.load_dataset("tips") 即可直接在线加载为 Pandas DataFrame。读者无需在本地准备或下载任何 CSV 文件,只要安装了 Seaborn 并在联网环境下运行代码,即可实现百分百效果复现

一、什么是 Seaborn

在 Python 数据科学与统计分析领域,如果说 Matplotlib 是数据可视化的基石,那么 Seaborn 就是建立在其之上的建筑。Seaborn 专门为统计图形和探索性数据分析设计,能够用极简的代码绘制出既美观又具备意义的图表


1. Seaborn 基本概念

Seaborn 是一个基于 Matplotlib 构建的高阶 Python 数据可视化库。它集成了常用的数据统计与拟合算法,并与 Pandas DataFrame 数据结构深度绑定

从底层设计理念来看,Seaborn 的核心特点体现在以下三个方面:

  • 统计表达:内置了均值计算、方差估计、置信区间拟合、核密度估计等统计逻辑,绘图的同时即可自动完成基础统计计算。

  • DataFrame 集成:直接以数据或 DataFrame 作为输入,无需手动对数据提取列表或进行循环分组

  • 视觉设计:内置了调和且专业的色彩搭配与图表主题样式,避免了 Matplotlib 默认样式偏古板的问题


2. 为什么基于 Matplotlib 构建

既然 Seaborn 功能如此强大且美观,为什么它不完全独立开发,而是选择作为 Matplotlib 的上层封装?这主要源于以下三个原因:

1. 继承底层能力

Matplotlib 经过二十余年的迭代,具备成熟且完善的底层图形渲染引擎(渲染画布、坐标系、几何图形绘制、图像导出等)。Seaborn 无需重复造轮子,而是将精力专注于上层的数据映射统计逻辑抽象

2. 消除冗长代码

在 Matplotlib 中,如果需要绘制带有置信区间的柱状图,或按照某一分类变量对数据点进行颜色分组,通常需要书写大量循环与统计计算代码

Seaborn 将这些高频的业务需求抽象为了单行 API 调用。例如:

import seaborn as sns
import matplotlib.pyplot as plt

# 载入内置示例数据集
tips = sns.load_dataset("tips")

# 仅需单行代码即可自动完成:数据分组、均值计算、置信区间估计以及绘图
sns.barplot(data=tips, x="day", y="total_bill", hue="sex")
plt.show()

3. 定制能力

由于 Seaborn 调用的底层依然是 Matplotlib 对象,因此 Seaborn 生成的所有图形,其返回值均为 Matplotlib 的 Axes 或 FacetGrid(基于 Figure)对象

这意味着:开发者可以使用 Seaborn 的 API 快速生成图形骨架,同时随时调用熟悉的 Matplotlib 方法进行局部微调

二、单变量数据可视化

数据分析的初始阶段,通常需要先了解单个变量的分布特征、集中趋势、离散程度以及离群点。Seaborn 针对单变量分析提供了绘图函数,按变量类型可分为直方图、核密度估计图与计数图


1. 直方图

直方图是观察连续型数值变量分布形态最基础的工具。Seaborn 的 histplot 在计算区间频数的同时,提供了丰富的统计量切分与区间调整选项

sns.histplot(data=None, x=None, y=None, hue=None, 
             stat='count', bins='auto', binwidth=None, kde=False, **kwargs)

data:数据源,通常为 Pandas DataFrame
x:指定要分析的连续型变量列名
bins:柱体数量,可传整数或字符串(默认 'auto')
binwidth:显示指定每个分箱的物理宽度(与 bins 二选一)
stat:纵轴的统计度量指标,常用选项:
    'count':频数
    'density':密度
    'probability':概率/频率
kde:布尔值,是否在直方图上方叠加密度估计曲线

代码示例

# 载入内置数据集
penguins = sns.load_dataset("penguins")

fig, ax = plt.subplots(figsize=(8, 4.5))

# 绘制企鹅体重分布直方图,并叠加密度曲线
sns.histplot(
    data=penguins,
    x="body_mass_g",
    bins=25,
    stat="count",
    kde=True,
    color="#2b5c8f",
    ax=ax
)

ax.set_xlabel("Body Mass (g)")
ax.set_ylabel("Count")
plt.show()

输出结果:


2. 核密度估计图

核密度估计是一种用于估计连续变量概率密度函数的非参数方法。相比于直方图受制于分箱边界的影响,KDE 能提供更平滑的概率密度分布曲线

sns.kdeplot(data=None, x=None, y=None, bw_adjust=1, 
            fill=False, cut=3, **kwargs)

x:分析的连续型变量
bw_adjust:带宽调节因子:
    值大于 1:曲线更平滑,但可能过度平滑局部细节
    值小于 1:曲线更贴合数据点,敏锐捕捉多峰特征,但容易受噪声干扰
fill:布尔值,是否填充曲线下方与 X 轴之间的区域
cut:控制曲线向数据极值之外延伸的距离

代码示例

penguins = sns.load_dataset("penguins")

fig, ax = plt.subplots(figsize=(8, 4.5))

# 绘制鳍肢长度的核密度估计图
sns.kdeplot(
    data=penguins, 
    x="flipper_length_mm", 
    bw_adjust=0.8, 
    fill=True, 
    color="#4c8be2", 
    alpha=0.4, 
    ax=ax
)

ax.set_xlabel("Flipper Length (mm)")
ax.set_ylabel("Density")
plt.show()

输出结果:


 


3. 计数图

对于离散的分类变量,分析师关注的通常是各个类别出现的频率或数量。countplot 本质上是针对分类变量的“自动频数统计柱状图”

与 barplot 的区别:barplot 纵轴呈现的是某连续变量的统计值;而 countplot 不需要指定纵轴变量,系统会自动统计横轴各分类的记录条数

sns.countplot(data=None, x=None, y=None, order=None, palette=None, **kwargs)

x 或 y:分类变量列名
    传 x:生成垂直方向的计数柱状图
    传 y:生成水平方向的计数柱状图
order:指定类别的显示顺序
palette:色彩调色板名称(如 'Set2', 'Blues_r')

代码示例:

penguins = sns.load_dataset("penguins")

fig, ax = plt.subplots(figsize=(8, 4))

# 按频数降序排列并绘制企鹅物种数量分布
species_order = penguins["species"].value_counts().index

sns.countplot(
    data=penguins, 
    y="species", 
    order=species_order, 
    palette="Blues_r", 
    ax=ax
)

ax.set_xlabel("Count")
ax.set_ylabel("Species")
plt.show()

输出结果:

三、双变量数据可视化

在完成单变量分布分析后,数据分析的关键步骤便过渡到双变量分析——分析两个变量之间的相互关系、影响趋势或组间差异

根据分析变量的类型组合(连续 vs. 连续、连续 vs. 分类),Seaborn 提供了丰富且高度抽象的绘图 API


1. 散点图

散点图用于展示两个连续变量之间的二维空间分布与相关性

sns.scatterplot(data=None, x=None, y=None, hue=None, 
                style=None, size=None, alpha=None, **kwargs)

x, y:指定作为横轴和纵轴的连续数值列名
hue:引入分类变量进行色彩映射
style:引入分类变量进行数据点形状映射(如圆点、方块、十字)
size:引入数值或分类变量映射数据点大小
alpha:透明度

代码示例

penguins = sns.load_dataset("penguins")
fig, ax = plt.subplots(figsize=(8, 4.5))

# 分析喙长与喙深的相关性
sns.scatterplot(
    data=penguins, 
    x="bill_length_mm", 
    y="bill_depth_mm", 
    hue="species", 
    alpha=0.8, 
    ax=ax
)

ax.set_xlabel("Bill Length (mm)")
ax.set_ylabel("Bill Depth (mm)")
plt.show()

输出结果:


2. 统计柱状图

不同于只计算频数的 countplot,barplot 用于呈现一个分类变量对应一个连续变量的统计聚合值,并自动计算置信区间

sns.barplot(data=None, x=None, y=None, estimator='mean', 
            errorbar=('ci', 95), **kwargs)

x:离散分类变量
y:连续数值变量(若 x 为数值 y 为分类,则生成水平柱状图)
estimator:聚合函数,默认为 'mean'
errorbar:误差棒设置,如 ('ci', 95) 表示 95% 置信区间,'sd' 表示标准差

代码示例

tips = sns.load_dataset("tips")
fig, ax = plt.subplots(figsize=(8, 4.5))

# 比较不同消费日期的平均消费及 95% 置信区间
sns.barplot(
    data=tips, 
    x="day", 
    y="total_bill", 
    estimator="mean", 
    errorbar=("ci", 95), 
    palette="Blues_d", 
    ax=ax
)

ax.set_xlabel("Day of Week")
ax.set_ylabel("Mean Total Bill ($)")
plt.show()

输出结果:


3. 箱线图

箱线图通过五数概括呈现分类变量下连续变量的分位数分布状况,是跨组对比集中趋势与识别离群点的标准工具

sns.boxplot(data=None, x=None, y=None, hue=None, 
            orient=None, width=0.8, **kwargs)

x:分类变量列名
y:连续变量列名
hue:二次分类维度,可在同一 X 轴分类下绘制并排对比箱线图
orient:指定箱线图方向,'v' 为垂直,'h' 为水平
width:箱体宽度比例

代码示例

tips = sns.load_dataset("tips")
fig, ax = plt.subplots(figsize=(8, 4.5))

# 跨用餐时段比较小费金额分布
sns.boxplot(
    data=tips, 
    x="time", 
    y="tip", 
    palette="Set2", 
    width=0.4, 
    ax=ax
)

ax.set_xlabel("Time of Day")
ax.set_ylabel("Tip Amount ($)")
plt.show()

输出结果:


4. 小提琴图

小提琴图结合了箱线图与核密度估计的优点。它不仅保留了分位数信息,还能直观展现数据在不同取值范围内的概率密度形状

sns.violinplot(data=None, x=None, y=None, hue=None, 
               split=False, inner='box', **kwargs)

split:当指定 hue 且该分类只有两个类别时,设为 True 可以将左右两半小提琴合并呈现
       节省空间并提升对比直观度
inner:内部表示形式,可选 'box'(微型箱线图)、'quart'(四分位数线)、'point'(数据点)或 None

代码示例:

tips = sns.load_dataset("tips")
fig, ax = plt.subplots(figsize=(8, 4.5))

# 结合性别对比不同用餐时段的消费金额分布
sns.violinplot(
    data=tips, 
    x="time", 
    y="total_bill", 
    hue="sex", 
    split=True, 
    inner="quartile", 
    palette="Pastel1", 
    ax=ax
)

ax.set_xlabel("Time")
ax.set_ylabel("Total Bill ($)")
plt.show()

输出结果:


5. 六边形蜂巢图

当数据量极其庞大(例如数十万个数据点)时,普通散点图会发生严重的数据点重叠,导致无法观察密度。六边形蜂巢图将二维空间划分为六边形网格,用颜色深浅表示落入网格内的点数频数

在 Seaborn 中,六边形图通常基于组合图接口 sns.jointplot 来调用

sns.jointplot(data=None, x=None, y=None, kind='hex', cmap='Blues', **kwargs)

kind:设为 'hex' 启用六边形分箱渲染
cmap:用于映射频数密度的色彩渐变表
gridsize:指定六边形网格的密致程度,值越大网格越细碎

代码示例

# 载入钻石数据集(数据量较庞大)
diamonds = sns.load_dataset("diamonds")

# 绘制克拉数与价格的六边形蜂巢图
g = sns.jointplot(
    data=diamonds, 
    x="carat", 
    y="price", 
    kind="hex", 
    cmap="Purples", 
    gridsize=30, 
    height=6
)

plt.show()

输出结果:


6. 二维核密度估计图

二维 KDE 图通过绘制等高线或填充颜色,呈现两个连续变量构成的二维联合概率密度分布,适合观察数据在连续空间中的聚类中心

sns.kdeplot(data=None, x=None, y=None, fill=False, 
            cmap=None, levels=10, thresh=0.05, **kwargs)

x, y:二元连续变量
fill:布尔值,是否填充等高线层级间的颜色
levels:等高线层级数量
thresh:最低密度阈值,用于滤除边缘极稀疏的数据区域

代码示例

geyser = sns.load_dataset("geyser")
fig, ax = plt.subplots(figsize=(8, 4.5))

# 绘制喷泉等待时间与喷发持续时间的二维核密度分布
sns.kdeplot(
    data=geyser, 
    x="waiting", 
    y="duration", 
    fill=True, 
    cmap="viridis", 
    levels=8, 
    ax=ax
)

ax.set_xlabel("Waiting Time (min)")
ax.set_ylabel("Eruption Duration (min)")
plt.show()

输出结果:

四、PairPlot

在探索性数据分析的早期阶段,如果数据集包含多个连续型数值变量,逐个绘制散点图去查看每两个变量之间的关系会极其耗时

sns.pairplot(两两关系图)能够自动提取数据集中的所有数值型特征,并在一个网格阵列中快速生成全变量两两组合的网格图


1. PairPlot 图表结构

PairPlot 的本质是一个 N * N 的子图矩阵(其中 N 为所选数值型变量的数量):

  • 对角线:由于对角线上的 X 轴与 Y 轴代表同一个变量,无法绘制双变量散点图,系统会自动将其替换为单变量的频数直方图或核密度估计图

  • 非对角线:展示两个不同变量之间的二维空间分布,用于快速判断变量之间是否存在线性/非线性相关性、正向/负向趋势或聚类特征


2. 方法签名与代码示例

sns.pairplot(data, *, hue=None, vars=None, 
             kind='scatter', diag_kind='auto', corner=False)

hue:指定分类变量,按类别进行色彩映射
vars:指定需要分析的连续变量列表,避免传入不必要的数值列
kind:非对角线图类型,常用 'scatter'(散点)或 'reg'(回归拟合线)
corner:设为 True 时仅绘制半三角,裁切镜像冗余信息并提升渲染速度

代码示例

penguins = sns.load_dataset("penguins")

# 筛选核心特征、颜色分组并开启半三角展示
sns.pairplot(
    data=penguins,
    vars=["bill_length_mm", "bill_depth_mm", "flipper_length_mm"],
    hue="species",
    corner=True
)

plt.show()

输出结果:

五、多变量

标准的二维图表默认只能在横轴与纵轴上呈现两个变量。当需要在一张图表里展现 3 到 5 个变量之间的协同关系或分组模式时,强行绘制三维图表通常会导致视觉遮挡与透视偏差

Seaborn 提供了对视觉通道的封装,允许开发者通过 hue、style 和 size 参数,将更多维度的变量叠加到二维图形中


1. 核心视觉通道

参数 视觉通道类型 数据类型 使用场景
hue 色彩(色相 / 饱和度) 离散分类或连续数值 最强烈的视觉区分通道,用于核心分类或数值梯度
style 点形状 / 线样式 离散分类 辅助区分维度(如圆点、方块;实线、虚线)
size 标记大小 / 线条粗细 连续数值或有序分类 呈现气泡图效果

2. 代码示例

在 sns.scatterplot 或 sns.lineplot 中,可以同时组合这些通道。以下示例展示了如何在同一张二维画布上清晰呈现 5 个不同的数据维度:

penguins = sns.load_dataset("penguins").dropna()
fig, ax = plt.subplots(figsize=(9, 5))

# 单图融合 5 个特征维度:
# X轴(喙长) + Y轴(喙深) + Color(物种) + Shape(性别) + Size(体重)
sns.scatterplot(
    data=penguins,
    x="bill_length_mm",      # 维度 1:连续数值
    y="bill_depth_mm",       # 维度 2:连续数值
    hue="species",           # 维度 3:分类变量(颜色映射)
    style="sex",             # 维度 4:二分类变量(点形状映射)
    size="body_mass_g",      # 维度 5:连续数值(点大小映射)
    sizes=(40, 200),         # 控制数据点最小与最大面积范围
    alpha=0.8,
    ax=ax
)

# 将图例放置在子图右侧外框,防止遮挡数据
ax.legend(bbox_to_anchor=(1.02, 1), loc='upper left', frameon=False)
plt.show()

输出结果:

尽管 Seaborn 支持叠加多个视觉通道,但在实际工程应用中需谨记认知负荷边界

  1. 控制维度上限:单图承载的变量建议控制在 3–4 个 以内。同时叠加过多通道(如既有复杂的颜色又有过于密集的形状)容易造成视觉噪音

  2. 通道优先级:人类大脑对色彩(hue)的感知敏感度远高于形状(style)与大小(size)。因此,最重要的核心分类变量必须优先分配给 hue

  3. 图例排版:当同时启用多个视觉通道时,系统会自动生成较长的组合图例。建议配合 bbox_to_anchor 将图例移至画布右侧外侧,保持绘图区域清晰

六、Seaborn Style

在完成了各类图表的绘制后,最后一步是统一整套分析报告或文章中的视觉风格。Seaborn 提供了一套简洁的接口,允许开发者无需繁琐调整 Matplotlib 参数,即可一键切换整套图表的背景、网格线与坐标系线条风格


1. 预设背景主题

Seaborn 内置了 5 种精心设计的预设背景主题,适用于不同的展示场景:

主题名称 视觉特征 推荐适用场景
darkgrid(默认) 浅灰背景 + 白色网格线 屏幕演示、数据密集的探索性分析
whitegrid 纯白背景 + 浅灰网格线 企业报告、学术论文、打印排版
dark 浅灰背景 + 无网格线 简洁对比风格
white 纯白背景 + 无网格线 极简图形呈现
ticks 纯白背景 + 显式坐标轴刻度线 经典统计学图表风格

API 方法签名

# 全局主题控制函数
sns.set_theme(style="whitegrid", palette="deep", font="sans-serif")

# 仅单独切换背景风格
sns.set_style("ticks")

在使用 white 或 ticks 主题时,图表的顶部和右侧外框线往往显得多余。Seaborn 提供了 sns.despine() 函数,可去除无意义的上方与右侧边框,使图形显得更轻盈干净

sns.despine(top=True, right=True, left=False, bottom=False)

2. 代码示例

以下示例展示了如何切换风格(whitegrid / ticks):

# 1. 全局应用 whitegrid 主题风格
sns.set_theme(style="whitegrid")
penguins = sns.load_dataset("penguins")
fig, ax = plt.subplots(figsize=(7, 4))

# 2. 绘制基础箱线图
sns.boxplot(data=penguins, x="species", y="body_mass_g", palette="Set2", ax=ax)

# 3. 移除上、右两侧的无用坐标轴线
sns.despine(top=True, right=True)

ax.set_xlabel("Species")
ax.set_ylabel("Body Mass (g)")
plt.show()

输出结果:

总结

本章介绍了 Seaborn 的基本使用方法,学习了单变量、双变量和多变量数据的可视化技巧,并掌握了核密度估计图、计数图、箱线图、小提琴图、二维核密度估计图、成对关系图等常用统计图表的绘制方法。同时,我们还学习了 Seaborn 的主题样式设置,能够更加便捷地绘制出美观且具有统计意义的数据图表

下一篇将继续学习 Pandas 数据可视化,利用 Pandas 内置的绘图功能快速完成常见图表的绘制,并进一步体会 Pandas、Matplotlib 与 Seaborn 在数据可视化中的不同定位和应用场景

Logo

Agent 垂直技术社区,欢迎活跃、内容共建。

更多推荐