3.2 折线图 lineplot 与聚合


文档摘要

3.2 折线图 lineplot 与聚合 lineplot 在同一 x 值出现多条观测时,默认聚合出均值并绘制 95% 置信区间——这是 Seaborn 中影响最深的一次隐式统计,理解它才能安全使用折线图。 承接 3.1:散点图不聚合,折线图默认聚合。这一动一静之间,藏着本章最重要的认知转折。 隐式聚合从哪来 同样的数据用 画,你会看到每个年份竖着落 12 个点。lineplot 做的事,等价于先 再连线,还附赠了误差估计。这笔"替你做的账",收益是趋势一眼可读,风险是样本量、离散度、分布形状全部被均值吞掉。 estimator 与 errorbar 的定制语法 参数的常用取值: (置信区间,默认 95%)、 (标准差)、 (中间 50% 分位区间)、 。

3.2 折线图 lineplot 与聚合

lineplot 在同一 x 值出现多条观测时,默认聚合出均值并绘制 95% 置信区间——这是 Seaborn 中影响最深的一次隐式统计,理解它才能安全使用折线图。

承接 3.1:散点图不聚合,折线图默认聚合。这一动一静之间,藏着本章最重要的认知转折。

隐式聚合从哪来

import seaborn as sns import matplotlib.pyplot as plt flights = sns.load_dataset('flights') # 每个年份有 12 个月共 12 条观测,直接画 x=year ax = sns.lineplot(data=flights, x='year', y='passengers') ax.set_ylabel('乘客数(月均值)') # 输出说明:每个年份的 12 条月度观测被聚成一个均值点, # 点周围的浅色竖带是 bootstrap 置信区间; # 曲线单调上升,带越到后期越宽——月度差异在变大

同样的数据用 sns.scatterplot 画,你会看到每个年份竖着落 12 个点。lineplot 做的事,等价于先 groupby('year').mean() 再连线,还附赠了误差估计。这笔"替你做的账",收益是趋势一眼可读,风险是样本量、离散度、分布形状全部被均值吞掉

estimator 与 errorbar 的定制语法

# 换统计量:中位数抗离群值 ax = sns.lineplot(data=flights, x='year', y='passengers', estimator='median') # 换误差口径:标准差代替置信区间 ax = sns.lineplot(data=flights, x='year', y='passengers', estimator='mean', errorbar='sd') # 完全关掉聚合:每条观测一条线(宽表时画出全部序列) ax = sns.lineplot(data=flights, x='year', y='passengers', estimator=None, errorbar=None, hue='month', legend=False, alpha=0.3) # 输出说明:12 条月度曲线叠成扇形,7、8 月在最外侧、2 月在最内侧—— # 旺季淡季的季节结构,在均值曲线里只是那条变宽的带

errorbar 参数的常用取值:'ci'(置信区间,默认 95%)、'sd'(标准差)、('pi', 50)(中间 50% 分位区间)、None。选哪个取决于你想让读者对"不确定性"还是"离散度"建立直觉:样本推总体用 ci,描述组内差异用 sd 或 pi。

旺季淡季的季节结构,在均值曲线里只是那条变宽的带

三个高频排错点

一是 x 乱序导致折线打结:lineplot 默认按 x 升序重排后再连线(sort=True),一旦为了保留观测顺序传入 sort=False,而数据本身不是按时间顺序采集的,曲线会在相邻点之间来回折返,看起来像剧烈震荡,其实只是绘制顺序问题——除非刻意要画观测路径,否则让排序保持默认。二是误差带与误差棒的切换:err_style='bars' 把半透明带换成竖棒,单序列或黑白打印时读数更准;多条 hue 序列并排时带状更抗混叠。按交付媒介切换即可,不必固定习惯。三是样式通道的连锁反应:给 style 分配变量后线型与标记会同时变化,默认再叠出点型就容易得到十几种组合的网格——只想改标记不动线型时,显式加 dashes=False 固定实线,并用 markers=['o', 's', 'D'] 指定有限的几种点型。样式通道的每一项都要主动确认,不能依赖默认轮换。

何时不该用折线图

折线的视觉语言是"相邻 x 值之间有连续过渡"。违反这个语义的用法都是陷阱:

# 反例一:类别 x 轴强行连线 ax = sns.lineplot(data=tips, x='day', y='total_bill') # Thursday 到 Friday 之间没有任何过渡含义,连线诱导读者读出不存在的趋势 # 正确做法:sns.pointplot 或 sns.barplot(第 4 章) # 反例二:时间不连续 gap = flights[~flights['year'].isin([1955, 1956])] # 抠掉两年 ax = sns.lineplot(data=gap, x='year', y='passengers') # 1954 直连 1957,曲线掩盖了数据缺口——应先标记缺失再决定是否断线

完整案例:月度趋势的正式汇报

背景:向运营汇报乘客量的季节规律,需要一张既能看趋势又能看波动的图。

操作

# 数据层:月列转为有序类别,保证 x 轴顺序正确 month_order = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] flights['month'] = pd.Categorical(flights['month'], categories=month_order, ordered=True) g = sns.relplot( data=flights, x='month', y='passengers', col='year', col_wrap=4, kind='line', estimator=None, # 每个面板只有一条真实序列,关掉聚合 height=2.4, aspect=1.3, ) g.set_xticklabels(rotation=45) g.set_xlabels('月份') g.set_ylabels('乘客数')

结果解读:12 个年度面板排成网格后,季节形态逐年稳定——每年 7 月见顶、2 月见底,且峰谷差逐年拉大。"季节结构稳定 + 总量增长放大波动",这两条结论正是一个仅靠均值折线说清的完整故事。变式:把 col 换成月、x 换成年,图形变成"各月的年度增长曲线",交叉验证趋势是否被季节掩盖。

⚠️ 常见坑:默认的 bootstrap 置信区间在大数据集上计算很慢。超过几万个点时,设 errorbar='sd'n_boot 减小,速度立刻回来(第 9 章性能专题还会回来谈这条)。

本节要点回顾

  • lineplot 默认聚合:等价于 groupby 均值加置信区间,样本信息被压缩;
  • estimator 决定统计量:中位数抗离群,None 保留每条序列;
  • errorbar 决定误差口径:ci 讲推断、sd 或 pi 讲离散;
  • 折线的语义前提:x 轴有序且相邻值之间过渡有意义,类别轴禁用;
  • 数据缺口要显式处理:抠掉的年份不能靠连线糊过去。

下一节把散点与折线装进 relplot 工厂,看分面语法如何统一两大关系图。


作者与出处
原作者: 灏天文库
来源:灏天文库
整理: 灏天文库整理
由灏天文库平台收录,内容或由平台用户上传,仅供学习交流
发布者: 作者: 灏天文库 转发
评论区 (0)
U