2.3 displot 与成对关系图 displot 是分布家族的 figure 级工厂,用 kind 切换直方图、密度、ecdf 并支持分面;jointplot 把两个变量的联合分布与各自边缘分布装进同一张图;pairplot 一次性画出所有数值列的两两关系矩阵。 2.1 与 2.2 拆的都是单坐标轴内的操作,本节升维:当分布问题多出一个类别维度(分面)或一个数值维度(联合、成对)时,映射层的 col 通道和 Grid 对象接管一切。这是第 7 章 Grid 家族的预演。 displot:kind 与 col 的组合语法 对照 2.2 里"分组 kde 出现曲线互相穿插"的情况,分面的价值一目了然:组内形态复杂、组间重叠严重时, 叠图不如 分面。
displot 是分布家族的 figure 级工厂,用 kind 切换直方图、密度、ecdf 并支持分面;jointplot 把两个变量的联合分布与各自边缘分布装进同一张图;pairplot 一次性画出所有数值列的两两关系矩阵。
2.1 与 2.2 拆的都是单坐标轴内的操作,本节升维:当分布问题多出一个类别维度(分面)或一个数值维度(联合、成对)时,映射层的 col 通道和 Grid 对象接管一切。这是第 7 章 Grid 家族的预演。
import seaborn as sns iris = sns.load_dataset('iris') # figure 级分布图:kind 决定图层,col 决定分面 g = sns.displot( data=iris, x='petal_length', col='species', # 分面通道:每个物种一个面板 kind='kde', # 图层类型:hist / kde / ecdf 三选一 fill=True, height=3, aspect=1.2, ) # 输出说明:三个面板共用 x 轴刻度,setosa 的峰远离另外两族, # 跨面板比较不需要读者自己在脑子里对齐坐标
对照 2.2 里"分组 kde 出现曲线互相穿插"的情况,分面的价值一目了然:组内形态复杂、组间重叠严重时,hue 叠图不如 col 分面。经验法则:组数不超过 6 用分面,超过 6 先考虑该不该聚合。
# 二维分面:col 加 row,两维类别同时铺开 penguins = sns.load_dataset('penguins').dropna() g = sns.displot( data=penguins, x='flipper_length_mm', col='species', row='sex', kind='hist', binwidth=3, ) # 输出说明:3 个物种 x 2 个性别共 6 个面板,同一列内性别可直接上下对照
col_wrap 用于只有 col 没有 row 时控制换行,比如 12 个月的数据 col='month', col_wrap=4 排成三行四列,比一行十二个窄条可读得多。
# 中央散点加边缘直方图,两个映射通道一次到位 g = sns.jointplot(data=penguins, x='bill_length_mm', y='bill_depth_mm', hue='species', height=6) # 输出说明:中央面板里三个物种呈明显的分层带; # 边缘面板自动按同一 hue 分组——喙长与喙深在全体数据上看是弱相关, # 分物种后各组内部甚至呈正相关,这就是著名的辛普森悖论在图形上的样子
换 kind 得到不同中央图层:
g = sns.jointplot(data=penguins, x='bill_length_mm', y='bill_depth_mm', kind='kde', hue='species', fill=False) # 中央变成等高线图:样本密集处线密,三个物种的"山头"位置与散点版互相印证 g = sns.jointplot(data=penguins, x='bill_length_mm', y='bill_depth_mm', kind='reg') # 中央散点加回归线加置信带,边缘换成单变量 kde——快速检查线性关系是否成立
jointplot 返回 JointGrid,中央与边缘可以分别定制,第 7.3 节会拆它的手动装配版。
g = sns.pairplot( data=iris, hue='species', # 颜色通道贯穿对角与非对角 corner=True, # 只画下三角,省一半版面 plot_kws={'alpha': 0.6, 's': 20}, # 非对角散点的细节参数 diag_kws={'fill': True}, # 对角 kde 的细节参数 ) # 输出说明:扫一遍矩阵即可完成特征筛选——petal_length 对 petal_width # 的面板里三个物种几乎线性可分;sepal_width 单看区分度最差。 # 这张图就是后续建模时"用哪几个特征"的第一手证据
pairplot 的读图顺序值得固化成习惯:先扫对角线(每个特征的组间分离度),再找非对角里"组间不重叠"的面板,最后回头检查这些面板对应的特征组合是否真的业务可解释。150 行的 iris 秒级出图;几千行时建议先抽样再画(第 9 章性能专题会给出抽样代码)。

一是 displot 的图例挤压面板:figure 级函数的图例默认挂在画布右侧,面板一多就开始互相侵占。改图例标题用 g.legend.set_title('物种');腾位置用 g.figure.subplots_adjust(right=0.82),把绘图区整体左移。这类调整要挂在 g(FacetGrid)上而不是 plt 上——第 1.2 节立过的两级分野,排错时最常被违反的就是这里。二是 jointplot 的边缘图层定制:marginal_kws={'bins': 25, 'rug': True} 把边缘直方图细分并叠上地毯层——中央面板由 kind 控制、边缘细节由 marginal_kws 下发,两个通道互不干扰,与 pairplot 的 plot_kws、diag_kws 完全同构,记住一套就等于记住三套。三是分面身份迷失:col 通道切出十几个面板后,单靠每格的列标题很难记住谁是谁,g.set_titles('{col_name} 月') 的模板语法给每个面板补上单位与语境,比事后在报告里逐张加注可靠得多。
⚠️ 常见坑:给 pairplot 喂含 id、年份这类"数值型标签列"的数据,矩阵里会多出无意义的面板。画前先用
vars=或df.select_dtypes('number')限定参与配对的列。
本节要点回顾
- 分面优于叠图的条件:组内形态复杂或组间重叠严重时,col 分面比 hue 叠图可读;
- jointplot 一次回答联合与边缘:辛普森悖论这类"总体与分组相关性相反"的现象,在它面前无所遁形;
- pairplot 是建模前的例行体检:读图顺序固定为对角线、强分离面板、业务复核;
- 细节参数分通道下发:plot_kws 管非对角、diag_kws 管对角,互不干扰;
- vars 限定列:防止标签列污染成对矩阵。
分布家族到此拆解完毕。第 3 章把映射层升级为两个数值列,关系图登场,聚合与置信区间将第一次进入拆解台。