Matplotlib 箱线图函数
箱线图,也叫做 “箱形图”。箱线图使用 6 个统计量来描述数据,也就是:最大值、上四分位数、中位数、下四分位数、最小值、异常值,如下图所示。

在 Matplotlib 中,我们可以使用 boxplot() 函数来绘制一个箱线图。其中,箱线图主要作用有 2 个:① 查看数据的分布情况;② 发现数据中的异常点。
语法:
plt.boxplot(x)说明:
x 是箱线图的数据。它可以是一维数据(如一维列表或 Series),也可以是二维数据(如二维列表或 DataFrame)。如果是一维数据,则表示绘制一个箱线图;如果是二维数据,则表示绘制多个箱线图。
示例 1:一个箱线图
import matplotlib.pyplot as plt
# 绘图
x = [0, 8, 1, 3, 6]
plt.boxplot(x)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
从箱线图可以看出,对于 x 这一组数据,它的最大值是 8、上四分位数是 6、中位数是 3、下四分位数是 1、最小值是 0。其中四分位数以及中位数的,这些都是数据分析中的概念。
示例 2:多个箱线图
import matplotlib.pyplot as plt
# 绘图
x1 = [0, 8, 1, 3, 6]
x2 = [16, 13, 10, 14, 12]
x3 = [20, 24, 21, 23, 27]
plt.boxplot([x1, x2, x3])
# 显示
plt.show()运行之后,效果如下图所示。

分析:
同时绘制多个箱线图也很简单,此时 boxplot() 函数接收一个列表作为参数就可以了。列表的每一个元素本身又是一个列表。
示例 3:异常值
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
plt.boxplot(x)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
对于 x 中的数据,大多数都是分布在 10 ~ 50 之间,但是这里的 80 和 90 已经远远超过这个范围了,所以 Matplotlib 会自动标识它们为异常值。其中图中的两个小圆圈代表的就是异常值(异常数据)。
需要清楚的是,异常值是箱线图自动识别的,而不是我们手动设置的。一般来说,如果某些数据不在大多数数据的范围,就会自动被标记为异常值。
Matplotlib 箱线图样式
为了让箱线图更加的美观,boxplot() 函数还提供了很多用于定义样式的参数,常用的如下表所示。
| 参数 | 说明 |
|---|---|
| notch | 是否有缺口,默认为 False(不带缺口) |
| vert | 是否为纵向,默认为 True(纵向) |
| showmeans | 是否显示平均值,默认为 False(不显示) |
| showfliers | 是否显示异常值,默认为 True(显示) |
| flierprops | 异常点的样式,值是一个字典 |
| boxprops | 箱子的样式,值是一个字典,需要结合 patch_artist=True 一起使用 |
| labels | 指定每个箱线图的标签 |
示例 4:带缺口
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
plt.boxplot(x, notch=True)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
notch=True 用于设置箱型图有缺口,缺口的作用其实非常简单,那就是为了突出中位数。
示例 5:横向显示
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
plt.boxplot(x, vert=False)
# 显示
plt.show()运行之后,效果如下图所示。

示例 6:显示平均值
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
plt.boxplot(x, showmeans=True)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
“平均值” 和 “中位数” 是两个完全不一样的东西,小伙伴们一定也要严格区分,别把它们给搞混了。
示例 7:隐藏异常值
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
plt.boxplot(x, showfliers=False)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
对于这个例子来说,它存在 2 个异常值:80 和 90。showfliers=False 用于隐藏异常值。
示例 8:异常点的样式
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
styles = {
'marker': 'D',
'markersize': 8,
'markerfacecolor': 'orange',
'markeredgecolor': 'red'
}
plt.boxplot(x, flierprops=styles)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
异常点的样式,可以通过 marker、markersize、markerfacecolor、markderedgecolor 这 4 个参数来定义的,说明如下表所示。
| 参数 | 说明 |
|---|---|
| marker | 外观 |
| markersize | 大小 |
| markerfacecolor | 颜色 |
| markeredgecolor | 边框颜色 |
示例 9:箱子的样式
import matplotlib.pyplot as plt
# 绘图
x = [23, 34, 11, 29, 33, 13, 33, 45, 80, 90]
styles = {
'facecolor': 'pink',
'edgecolor': 'red',
}
plt.boxplot(x, patch_artist=True, boxprops=styles)
# 显示
plt.show()运行之后,效果如下图所示。

分析:
想要使得 boxprops 生效,我们必须先设置 patch_artist=True。boxprops 和 patch_artist 这 2 个参数都是配合一起使用的。此外,facecolor 用于定义箱子颜色,而 edgecolor 用于定义边框颜色。
示例 10:标签说明
import matplotlib.pyplot as plt
# 绘图
x1 = [0, 8, 1, 3, 6]
x2 = [16, 13, 10, 14, 12]
x3 = [20, 24, 21, 23, 27]
plt.boxplot([x1, x2, x3], labels=['A', 'B', 'C'])
# 显示
plt.show()运行之后,效果如下图所示。

分析:
当同时绘制多个箱线图时,我们可以使用 labels 参数来给每一个箱线图定义标签说明。从上面可以看出来,箱线图本身其实非常简单,大家不要因为之前没有接触过,就被它可怕的外表给欺骗了。
最后需要说明的是,箱线图和散点图有点类似,它们非常适用于快速找出数据中的异常值,这个对于我们数据分析是非常有用的。
Matplotlib 箱线图案例
在当前项目下的 data 文件夹中有一个 staff.csv 文件,项目结构如下图所示。其中 staff.csv 文件保存的是所有员工的年龄,内容如下图所示。接下来我们尝试使用箱线图来判断年龄是否存在异常值。


示例 11:Matplotlib 箱线图的实际应用
import pandas as pd
import matplotlib.pyplot as plt
# 设置
plt.rcParams['font.family'] = ['SimHei', 'PingFang SC']
plt.rcParams['axes.unicode_minus'] = False
# 读取数据
df = pd.read_csv('data/staff.csv')
# 绘制图表
styles = {
'markerfacecolor': 'red',
'markeredgecolor': 'red'
}
plt.boxplot(df['年龄'], flierprops=styles)
plt.title('员工年龄箱线图')
# 显示
plt.show()运行之后,效果如下图所示。

分析:
从结果可以看出来,年龄这一列存在 2 个异常点。那么是不是箱线图就一定能判断出异常值呢?那可不一定。比如我们修改一下 staff.csv,也就是将小明的年龄修改成 142,如下图所示。再次运行代码,此时效果就变成如下图所示了。


为什么这个时候箱线图就没能把异常值给找出来呢?这是因为对于 staff.csv 这个数据集来说,它的异常值所占比例已经比较大了,此时箱线图会把这些异常值当做是正常值来看待。当然了,当样本数量足够多时,箱线图还是可以非常准确地判断异常值的。
从上面我们也应该知道,箱线图只是一个辅助工具,并不能保证一定能判断出异常值。所以在实际工作中,我们除了借助可视化库之外,也要结合自己的业务经验,这样才能准确判断。
