1.3 内置数据集与数据长表 长表(整洁数据)是每行一条观测、每列一个变量的表结构,是 Seaborn 映射语法的母语;宽表则以一行多个度量列的形式存储,需要先融化成长表才能顺畅映射。 前两节解决了"怎么看图"和"怎么出图",本节解决"数据从哪来"。它是第 1 章的收尾,也是后面八章所有案例的数据供给站。 五个内置数据集 从官方仓库拉取示例数据,首次联网下载后会缓存到本地。 选这五个不是随意的:tips 用来讲类别映射,iris 用来讲成对关系,flights 天生是长表时间序列,titanic 有缺失值和离散统计,penguins 适合数值相关性。一个数据集配一类语法问题。 长表为什么是母语 设想一个场景:三个部门的季度销售额,存在一张宽表里。
长表(整洁数据)是每行一条观测、每列一个变量的表结构,是 Seaborn 映射语法的母语;宽表则以一行多个度量列的形式存储,需要先融化成长表才能顺畅映射。
前两节解决了"怎么看图"和"怎么出图",本节解决"数据从哪来"。它是第 1 章的收尾,也是后面八章所有案例的数据供给站。
sns.load_dataset 从官方仓库拉取示例数据,首次联网下载后会缓存到本地。
import seaborn as sns # 教程全程使用的五个数据集一览 for name in ['tips', 'iris', 'flights', 'titanic', 'penguins']: df = sns.load_dataset(name) print(f"{name:10s} 形状 {df.shape}") # 输出示例: # tips 形状 (244, 7) 小费:总消费、小费、餐段、星期等 # iris 形状 (150, 5) 鸢尾花:四个测量值加物种 # flights 形状 (144, 3) 航班:年、月、乘客数 # titanic 形状 (891, 15) 泰坦尼克:乘客信息与生还 # penguins 形状 (344, 8) 企鹅:体型测量加物种岛屿
选这五个不是随意的:tips 用来讲类别映射,iris 用来讲成对关系,flights 天生是长表时间序列,titanic 有缺失值和离散统计,penguins 适合数值相关性。一个数据集配一类语法问题。
titanic = sns.load_dataset('titanic') print(titanic.dtypes.value_counts()) # 输出示例: # object 7 # int64 4 # float64 3 # bool 1 # 说明:列类型分布决定它适合哪些映射——数值列进连续通道,object 列进离散通道
设想一个场景:三个部门的季度销售额,存在一张宽表里。
import pandas as pd wide = pd.DataFrame({ 'quarter': ['Q1', 'Q2', 'Q3', 'Q4'], 'east': [120, 132, 128, 140], 'west': [98, 105, 112, 118], 'north': [76, 80, 84, 90], })
想画"季度 x 销售额,按部门着色"的折线图,宽表直接映射不了——hue 需要一个"部门"列,而部门名现在藏在表头里。融化成长表:
long = wide.melt(id_vars='quarter', var_name='region', value_name='sales') print(long.head(4)) # 输出: # quarter region sales # 0 Q1 east 120 # 1 Q2 east 132 # 2 Q3 east 128 # 3 Q4 east 140 # 融化后,映射立刻成立 ax = sns.lineplot(data=long, x='quarter', y='sales', hue='region')
规律可以推广:凡是"按某维度着色/分面/改点型"的需求,那个维度必须是长表里的一列。宽表把维度编码进了列名,语法层就够不着它。
反向操作同样常见。flights 是天然长表,但热力图需要"行 x 列"的矩阵形态,这时用透视:
flights = sns.load_dataset('flights') pivot = flights.pivot(index='month', columns='year', values='passengers') print(pivot.iloc[:2, :3]) # 输出: # year 1949 1950 1951 # month # January 112 115 145 # February 118 126 150 # 说明:pivot 是 melt 的逆操作,热力图与聚类图(第 5 章)只吃矩阵形态
melt 与 pivot 这对互逆操作,是数据层最重要的两个工具:映射前 melt,画矩阵图前 pivot。
同一个数值,存成 float64 和存成 object,映射结果完全不同。
tips = sns.load_dataset('tips') tips['size_str'] = tips['size'].astype(str) # 用餐人数:整数 → 字符串 # 数值型:颜色连续渐变,图例带数值刻度 ax1 = sns.scatterplot(data=tips, x='total_bill', y='tip', hue='size') # 字符串型:同样的数字,变成离散色块,图例逐类列出 ax2 = sns.scatterplot(data=tips, x='total_bill', y='tip', hue='size_str')
哪种对?取决于语义:用餐人数 2 和 4 之间没有"2.8 人",离散更合理;而年龄、收入这类真连续量用渐变才不丢信息。类似的坑还有:类别列被读成数字(如用 0/1 编码的性别),hue 会错误地走连续刻度,图例变成色带。习惯性检查 df.dtypes,是绘图前的标准动作。
# 把 0/1 编码列恢复为类别,映射回到离散轨道 tips['smoker_code'] = tips['smoker'].map({'Yes': 1, 'No': 0}) tips['smoker_code'] = tips['smoker_code'].astype('category') print(tips['smoker_code'].dtype) # 输出:category
💡 关键直觉:数据层多花的每一分钟,都会在映射层省回来。列名起清楚、类型转对、该融化的融化,后面的绘图代码通常只剩三五行。

本节要点回顾
- 五个数据集各司其职:tips 讲类别、iris 讲成对关系、flights 讲长表时序、titanic 讲缺失与离散、penguins 讲相关;
- 维度必须是列:着色、分面、点型的依据列不存在时,先 melt 再画;
- melt 与 pivot 互逆:映射语法吃长表,矩阵图吃透视表;
- dtype 即刻度:float 走连续渐变,object 与 category 走离散色板,画前必查;
- 派生列先行:比率、分类、单位换算都在数据层完成。
第 1 章到此收官。第 2 章把拆解台转向第一个图形家族:分布图,从最简单的单变量映射开始。