查看全课大纲(第 77 / 101 节)
  1. 1.数据分析基本概念
  2. 2.学习数据分析的一般路线
  3. 3.数据分析的流程
  4. 4.数据类型
  5. 5.环境部署(1)
  6. 6.环境部署(2)
  7. 7.课程介绍
  8. 8.TXT文件操作
  9. 9.JSON文件操作
  10. 10.CSV文件操作
  11. 11.Excel文件操作
  12. 12.数据库及SQL常用语法
  13. 13.数据库基本操作
  14. 14.数据库多表连接
  15. 15.实战:欧洲职业足球数据库分析
  16. 16.爬虫简介
  17. 17.URL管理模块
  18. 18.网页下载模块
  19. 19.网页解析模块(1)
  20. 20.网页解析模块(2)
  21. 21.Scrapy简介
  22. 22.Scrapy使用步骤(1)
  23. 23.Scrapy使用步骤(2)
  24. 24.Scrapy使用步骤(3)
  25. 25.Scrapy使用步骤(4)
  26. 26.实战:获取国内城市空气质量指数数据
  27. 27.NumPy和SciPy介绍
  28. 28.多维数组
  29. 29.多维数组操作
  30. 30.NumPy的常用方法
  31. 31.向量化介绍
  32. 32.向量化及通用函数
  33. 33.实战:2016美国大选分析
  34. 34.数据结构-Series
  35. 35.数据结构-DataFrame
  36. 36.数据结构-Index
  37. 37.Series的索引操作
  38. 38.DataFrame的索引操作
  39. 39.索引操作总结
  40. 40.运算与对齐
  41. 41.函数应用操作(1) -- map
  42. 42.函数应用操作 (2) -- apply applymap
  43. 43.文件读写操作
  44. 44.排序操作
  45. 45.数据清洗--处理缺失数据
  46. 46.数据清洗--处理重复数据
  47. 47.数据清洗--替换数据
  48. 48.常用统计方法(1) -- describe quantile
  49. 49.常用统计方法(2) -- sum mean median count
  50. 50.常用统计方法(3) -- max min idxmax idxmin
  51. 51.常用统计方法(4) -- mad var std cumsum
  52. 52.实战:全球食品数据分析
  53. 53.层级索引
  54. 54.分组与聚合介绍
  55. 55.分组操作(1) -- GroupBy对象及常用聚合操作
  56. 56.分组操作(2) -- 自定义分组及聚合操作
  57. 57.透视表介绍
  58. 58.透视表操作
  59. 59.数据规整(1) -- 数据合并concat
  60. 60.数据规整(2) -- 数据连接merge
  61. 61.数据重构(3) -- 数据重构stack unstack
  62. 62.实战:互联网电影资料库分析
  63. 63.探索性数据分析EDA介绍
  64. 64.EDA的目的
  65. 65.EDA常用工具
  66. 66.Matplotlib绘图基本介绍
  67. 67.Matplotlib画布
  68. 68.散点图和柱状图的绘制
  69. 69.直方图的绘制
  70. 70.矩阵绘图
  71. 71.子图的使用
  72. 72.Matplotlib颜色、标记、线型
  73. 73.Matplotlib坐标刻度、标签、图例、标题
  74. 74.Seaborn介绍
  75. 75.数据集分布可视化(1) -- 单变量分布、双变量分布
  76. 76.数据集分布可视化(2) -- 变量关系可视化
  77. 77.类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
  78. 78.交互式数据可视化工具Bokeh介绍
  79. 79.Bokeh绘制散点图、柱状图、盒子图、弦图
  80. 80.Bokeh绘制常用图形元素
  81. 81.3D绘图 -- mplot3d
  82. 82.3D曲线可视化
  83. 83.3D散点图可视化
  84. 84.3D柱状图可视化
  85. 85.Pandas绘图
  86. 86.实战:Lending Club借贷数据探索性分析及可视化
  87. 87.机器学习介绍及应用场景
  88. 88.机器学习建模介绍 (1) -- 分类
  89. 89.机器学习建模介绍 (2) -- 回归
  90. 90.机器学习建模介绍 (3) -- 聚类
  91. 91.机器学习分类
  92. 92.机器学习工具scikit-learn
  93. 93.使用scikit-learn的流程
  94. 94.数据集准备及划分
  95. 95.模型选择
  96. 96.数据预处理及特征工程
  97. 97.过拟合与欠拟合
  98. 98.模型调参介绍
  99. 99.模型调参方法
  100. 100.模型测试及评价
  101. 101.实战:通过移动设备行为数据预测性别和年龄

类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图

约 13 分钟

📺 正在播放小象学院官方高清录播(支持倍速与清晰度调节)

类别数据可视化

小象实战讲义 · Python数据分析实战

在上一讲中,我们学习了如何使用 Seaborn 绘制变量间的关系图。本讲我们将聚焦于类别数据的可视化。当数据中至少有一列是类别型(如星期几、性别、产品类型)时,如何直观地展示其与数值型数据的关系、分布及统计特征?这正是本讲要解决的问题。学完后,你将掌握三种核心的类别数据可视化工具。

💡 核心导读

  • 类别散布图:使用 stripplot 和 swarmplot 展示类别与数值的对应关系,可直观看到数据点的分布。
  • 类别内数据分布:通过 盒子图 (boxplot) 和 小提琴图 (violinplot) 深入理解每个类别下数据的统计分布(如四分位数、离群值)。
  • 类别内统计图:利用 柱状图 (barplot) 和 点图 (pointplot) 快速比较不同类别的统计量(如均值),并支持分组展示。
  • 统一参数:这些函数共享 x, y, data, hue 等核心参数,用法简洁高效。

类别散布图

类别散布图用于展示一个类别型变量与一个数值型变量之间的关系。Seaborn 提供了两种主要的散布图:stripplot(分布散点图)和 swarmplot(分簇散点图)。它们都接受以下核心参数:

  • x, y:指定要可视化的两列数据。
  • data:包含数据的 DataFrame。
  • hue:用于在图中引入第二个类别维度,进行分组着色。

关键区别:之前学习的变量间关系图(如散点图)要求两列数据都是数值型。而类别散布图要求至少有一列是类别型数据。

我们将使用 Seaborn 内置的 tips(小费)数据集进行演示。该数据集记录了餐厅顾客的消费信息。

import seaborn as sns
import matplotlib.pyplot as plt

# 使用无界面后端,确保代码在任何环境均可运行
plt.switch_backend('Agg')

# 加载小费数据集
tips_data = sns.load_dataset('tips')
print("数据预览(前5行):")
print(tips_data.head())
数据预览(前5行):
   total_bill   tip     sex smoker  day    time  size
0       16.99  1.01  Female     No  Sun  Dinner     2
1       10.34  1.66    Male     No  Sun  Dinner     3
2       21.01  3.50    Male     No  Sun  Dinner     3
3       23.68  3.31    Male     No  Sun  Dinner     2
4       24.59  3.61  Female     No  Sun  Dinner     4

现在,我们绘制一个基础的类别散布图,查看一周中不同日子(day,类别型)收到的小费(tip,数值型)情况。

import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')

# 重新加载数据以确保代码块自包含
tips_data = sns.load_dataset('tips')

# 绘制分布散点图 (stripplot)
fig, ax = plt.subplots(figsize=(8, 4))
sns.stripplot(x='tip', y='day', data=tips_data, ax=ax)
ax.set_title('小费金额在不同日期的分布(stripplot)')
# 讲义中不实际保存图片,此处仅作演示,关闭图形释放内存
plt.close(fig)
print("已绘制 stripplot:x轴为小费金额,y轴为星期几。")
已绘制 stripplot:x轴为小费金额,y轴为星期几。

从图中(想象或运行代码可见)可以看出,周六(Sat)有一些小费金额较高的点。为了更清晰地展示数据分布并引入第二个分类维度(如性别),我们可以使用 swarmplot,并设置 hue 参数。

import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')

tips_data = sns.load_dataset('tips')

# 绘制分簇散点图 (swarmplot),并按性别(hue)分组着色
fig, ax = plt.subplots(figsize=(8, 4))
sns.swarmplot(x='tip', y='day', data=tips_data, hue='sex', ax=ax)
ax.set_title('按性别分组的小费金额分布(swarmplot)')
plt.close(fig)
print("已绘制 swarmplot,并依据‘sex’列进行分组着色。")
print("观察:周六(Sat)给出较高小费的顾客中,男性(蓝色点)似乎更多。")
已绘制 swarmplot,并依据‘sex’列进行分组着色。
观察:周六(Sat)给出较高小费的顾客中,男性(蓝色点)似乎更多。

swarmplot 会将数据点“分簇”排列,避免重叠,使得分布更加清晰。通过 hue='sex',我们进一步发现,在周六给出较高小费的顾客中,男性居多。这展示了类别散布图在探索数据细节上的强大能力。

类别内数据分布

当我们需要深入理解每个类别下数值数据的分布情况(而不仅仅是单个数据点)时,盒子图和小提琴图是更强大的工具。

盒子图 (Box Plot)

盒子图,又称箱线图,是一种用于显示数据分布情况的标准化方法。它基于分位数概念,能够展示数据的中位数、四分位数、范围以及潜在的离群值。

让我们回顾一下分位数:如果将一组数据从小到大排序,25%分位数(Q1)是第25%位置的数,50%分位数即中位数(Q2),75%分位数(Q3)是第75%位置的数。

一个标准的盒子图包含以下元素:

  1. 盒子本身:下边缘是 Q1,上边缘是 Q3,盒子中间的线是中位数(Q2)。盒子的高度就是 四分位距 (IQR) = Q3 - Q1。
  2. 须(Whiskers):通常从盒子边缘延伸出去的两条线。在 Seaborn 的默认设置中,它们表示非离群值的范围。
    • 上须的顶端位于 Q3 + 1.5 * IQR
    • 下须的底端位于 Q1 - 1.5 * IQR
  3. 离群值(Outliers):任何超出须的范围的数据点,会被单独绘制为散点,通常被认为是与主体分布偏离较大的值。
import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')

tips_data = sns.load_dataset('tips')

# 绘制盒子图
fig, ax = plt.subplots(figsize=(8, 4))
sns.boxplot(x='day', y='tip', data=tips_data, ax=ax)
ax.set_title('不同日期小费金额的分布(盒子图)')
plt.close(fig)
print("已绘制盒子图。")
print("解读:每个‘盒子’展示了该日期下小费金额的Q1、中位数、Q3。")
print("     盒子外的散点是可能的离群值,例如周六有一个非常高的小费。")
已绘制盒子图。
解读:每个‘盒子’展示了该日期下小费金额的Q1、中位数、Q3。
     盒子外的散点是可能的离群值,例如周六有一个非常高的小费。

同样,我们可以使用 hue 参数绘制分组的盒子图,以比较不同子类别(如性别)在主要类别(如日期)内的分布。

import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')

tips_data = sns.load_dataset('tips')

# 绘制分组盒子图
fig, ax = plt.subplots(figsize=(10, 4))
sns.boxplot(x='day', y='tip', data=tips_data, hue='sex', ax=ax)
ax.set_title('按性别分组的不同日期小费分布(盒子图)')
plt.close(fig)
print("已绘制分组盒子图。")
print("可以直观比较同一天内,男性和女性给出小费金额分布的差异。")
已绘制分组盒子图。
可以直观比较同一天内,男性和女性给出小费金额分布的差异。

小提琴图 (Violin Plot)

小提琴图是盒子图的一种增强。它结合了盒子图和核密度估计(KDE)的特点。小提琴的宽度反映了数据在该值附近的密度,即数据越集中的地方,小提琴越宽。因此,小提琴图能比盒子图更细致地展示数据的实际分布形状(如双峰、偏态)。

import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')

tips_data = sns.load_dataset('tips')

# 绘制小提琴图
fig, ax = plt.subplots(figsize=(8, 4))
sns.violinplot(x='day', y='tip', data=tips_data, ax=ax)
ax.set_title('不同日期小费金额的分布(小提琴图)')
plt.close(fig)
print("已绘制小提琴图。")
print("解读:图形宽度代表数据密度。可以观察分布的形态,例如是否对称、是否有多个峰值。")
已绘制小提琴图。
解读:图形宽度代表数据密度。可以观察分布的形态,例如是否对称、是否有多个峰值。

同样,小提琴图也支持 hue 参数进行分组比较。

类别内统计图

有时我们并不关心每个类别的完整分布,而只想快速比较不同类别的某个统计量(如平均值)。这时,柱状图和点图就派上用场了。

  • sns.barplot():默认显示每个类别数值的平均值,并通过误差线(通常表示置信区间)展示估计的可靠性。柱子的高度直观代表了均值的大小。
  • sns.pointplot():同样默认显示均值,但用点和连线来表示。点图特别适合展示跨类别的趋势,因为连线可以清晰地指示上升或下降的走向。
import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')

tips_data = sns.load_dataset('tips')

# 绘制分组柱状图 (比较不同日期、不同性别的小费平均值)
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 4))
sns.barplot(x='day', y='tip', data=tips_data, hue='sex', ax=ax1)
ax1.set_title('小费平均金额(柱状图)')

# 绘制分组点图
sns.pointplot(x='day', y='tip', data=tips_data, hue='sex', ax=ax2)
ax2.set_title('小费平均金额趋势(点图)')

plt.tight_layout()
plt.close(fig)
print("已绘制分组柱状图和点图。")
print("柱状图:比较不同组别的均值大小。")
print("点图:观察均值随日期变化的趋势。例如,女性给的小费均值从周四到周日似乎呈上升趋势。")
已绘制分组柱状图和点图。
柱状图:比较不同组别的均值大小。
点图:观察均值随日期变化的趋势。例如,女性给的小费均值从周四到周日似乎呈上升趋势。

可以看到,使用 Seaborn 绘制这些复杂的统计图非常简洁,一行代码就替代了使用 Matplotlib 时需要手动计算统计量、设置标签、图例等大量代码,极大地提升了数据分析与可视化的效率。

📝 动手练一练

  1. 概念辨析:stripplot 和 swarmplot 都是类别散布图,它们最主要的区别是什么?在什么情况下你会优先选择 swarmplot?
👉 点击查看参考答案

stripplot 和 swarmplot 最主要的区别在于数据点的排列方式。stripplot 可能会因为数据点过多而出现重叠,导致分布看不清楚。swarmplot 则会对数据点进行“分簇”或“抖动”处理,避免重叠,从而更清晰地展示数据在类别轴上的分布密度。当数据量不是特别大,且你想更清晰地观察每个类别下数据点的分布情况时,应优先选择 swarmplot。但请注意,对于非常大的数据集,swarmplot 的计算和绘制可能会比较慢。

  1. 动手实践:使用 tips 数据集,尝试将 sns.boxplot(x='day', y='tip', data=tips_data, hue='sex') 中的 x 和 y 参数对调,即改为 sns.boxplot(x='tip', y='day', ...)。观察生成的图形发生了什么变化?这种变化在解读数据时有什么不同的侧重点?
👉 点击查看参考答案
import seaborn as sns
import matplotlib.pyplot as plt
plt.switch_backend('Agg')
tips_data = sns.load_dataset('tips')
fig, ax = plt.subplots(figsize=(8,4))
sns.boxplot(x='tip', y='day', data=tips_data, hue='sex', ax=ax)
ax.set_title('交换x和y轴后的盒子图')
plt.close(fig)
print("图形已生成(想象或运行代码可见)。")
图形已生成(想象或运行代码可见)。

变化:对调 x 和 y 后,类别(day)变成了纵轴,数值(tip)变成了横轴。盒子从垂直方向变成了水平方向。 解读侧重点:视觉上,水平盒子图更便于阅读较长的类别标签(如果类别名很长)。在解读时,我们仍然是观察每个类别(行)的数据分布。这种形式有时在报告或仪表板中因排版需要而被采用,其表达的统计信息与垂直盒子图完全一致。

本章小结

本讲我们深入学习了 Seaborn 中用于类别数据可视化的三大类图形:

  1. 类别散布图 (stripplot, swarmplot):直观展示类别与数值的对应关系,swarmplot 能避免重叠,显示更清晰。
  2. 类别内数据分布图 (boxplot, violinplot):
    • 盒子图 精炼地展示了数据的四分位数、中位数、范围及离群值,是进行数据分布比较和异常值检测的利器。
    • 小提琴图 在盒子图的基础上增加了核密度估计,能揭示数据分布的具体形状(如双峰、偏态)。
  3. 类别内统计图 (barplot, pointplot):快速比较不同类别的统计量(默认是均值)。柱状图侧重比较大小,点图侧重展示趋势。

所有这些方法都共享 x, y, data, hue 这一套简洁而强大的参数体系,使得在 Seaborn 中进行复杂的多维度类别数据可视化变得异常高效。

📋 行动清单

  • 在本地或线上环境运行本讲的示例代码,亲手生成每一幅图,并尝试修改参数(如调换 x、y,更换 hue 的列)。
  • 为你手头的一个数据集(至少包含一个类别列和一个数值列)分别绘制盒子图和小提琴图,对比两者在揭示数据分布信息上的异同。
  • 思考:如果你想展示“不同产品类别(类别)的月销售额(数值)随时间(另一个类别,如月份)的变化趋势”,结合本讲知识,你会选择哪种图形?为什么?(提示:考虑使用 pointplot 并设置 hue 为产品类别,x 为月份)。

—— 小象教研组

配套资料 · 直接下载

课件、代码、数据集等配套资料全部免费,点击即可直接下载,无需分享或解锁。

  • 本节课件:类别数据可视化 -- 类别散布图、类别内数据分布、类别内统计图
    PDF · 380KB
    下载
  • 全套课件打包(第1-5章)
    ZIP · 12.8MB
    下载
  • 全套课件打包(第6-8章)
    ZIP · 15MB
    下载
  • 实战数据集:AppleStore 应用商城分析
    ZIP · 329KB
    下载
  • 实战数据集:女性服装电商分析
    ZIP · 2.8MB
    下载
  • Python 数据分析环境搭建指南
    PDF · 2MB
    下载
  • Scrapy 安装教程
    PDF · 12.7MB
    下载
  • 附加实战项目:AppleStore 应用商城数据分析
    ZIP · 0.3MB · ipynb + CSV 数据
    下载
  • 附加实战项目:银行电话营销数据分析
    ZIP · 0.4MB · ipynb + CSV 数据
    下载
  • 附加实战项目:女性服装电商评论数据分析
    ZIP · 2.7MB · ipynb + CSV 数据
    下载
  • 附加实战项目:美国化学学会杂志数据分析
    ZIP · 34.2MB · ipynb + SQLite 数据库
    下载