Seaborn 小提琴图

Seaborn 小提琴图函数

小提琴图,是一种组合型的图表,它同时结合了箱线图核密度图的功能。在 Seaborn 中,我们可以使用 violinplot() 函数来绘制一个小提琴图。

语法:

sns.violinplot(data, x, y)

说明:

violinplot() 函数接收以下 3 个参数。

  • data(可选):用于定义数据部分,它是一个 DataFrame。
  • x(可选):用于指定 DataFrame 的哪一列作为 x 轴坐标。
  • y(可选):用于指定 DataFrame 的哪一列作为 y 轴坐标。

示例 1:Seaborn 绘制小提琴图

import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 数据
data = [
    ['张三', 24],
    ['李四', 18],
    ['王五', 37],
    ['小芳', 24],
    ['小红', 12],
    ['小明', 42],
    ['小华', 56],
    ['小莉', 67],
    ['小英', 45],
    ['小军', 82]
]
df = pd.DataFrame(data, columns=['姓名', '年龄'])
# 绘图
sns.violinplot(data=df, y='年龄')

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图

分析:

sns.violinplot(data=df, y='年龄') 表示使用 df 作为数据来源,然后 “年龄” 作为 y 轴坐标。从图中可以看到,20 ~ 40 之间面积最大,也就说明处于 20 ~ 40 之间的数据最多。小伙伴们自行数一下就知道了。

Seaborn 小提琴图案例

Seaborn 内置了一个数据集 tips,该数据集保存的是某餐厅的营业情况,包括账单、小费、客人信息等,部分内容如下图所示。需要说明的是,“size” 这一列指的是客人订的餐桌类型,比如有些是 2 人桌、有些是 3 人桌等。

Seaborn tips 数据集

示例 2:基本小提琴图

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, y='账单')

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图纵向显示

分析:

如果想要使得小提琴图是横向的,我们可以将 y='账单' 改为 x='账单',此时效果如下图所示。

Seaborn 小提琴图横向显示

示例 3:多个小提琴图

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单')

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 多个小提琴图

分析:

对于这个例子来说,x 轴坐标是 “星期”,取值共有 4 种:Thur(周四)、Fri(周五)、Sat(周六)、Sun(周日)。然后 y 轴坐标是 “账单”。由于 “星期” 共有 4 种取值,所以这里绘制了 4 个小提琴图出来,每一个小提琴图都是独立的。

对于这个例子来说,如果想要将小提琴图改为横向显示,我们只需要将 x 和 y 这两个参数的取值调换就可以了。修改后的代码如下,此时效果如下图所示。

sns.violinplot(data=df, x='账单', y='星期')

Seaborn 多个小提琴图横向显示

示例 4:添加区分

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单', hue='性别')

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图添加区分

分析:

对于 violinplot() 函数来说,它也是只有 hue 参数,而没有 style 和 size 这 2 个参数。所以想要添加区分,我们只能使用 hue 参数来实现。

当然了,对于这个例子来说,如果我们将 hue='性别' 改为 hue='是否吸烟',此时就会使用 “是否吸烟” 这一列作为分类来源,效果如下图所示。

Seaborn 小提琴图 hue='是否吸烟'

示例 5:合并显示

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单', hue='性别', split=True)

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图合并显示

分析:

当 hue='性别' 时,由于 “性别” 只有 “Male” 和 “Female” 这 2 种取值,所以每一列就使用了 2 种不同颜色的小提琴图来显示。如果我们希望只使用一个小提琴图来显示,小提琴的左边是 “Male” 的数据分布,小提琴的右边是 “Female” 的数据分布,此时可以使用 split=True 这个参数来显示。

示例 6:改变顺序

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单', order=['Sun', 'Sat', 'Fri', 'Thur'])

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图改变顺序

分析:

如果想要改变顺序,我们可以使用 order 参数来实现。

示例 7:添加百分位线

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单', inner='quartile')

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图添加百分位线

分析:

我们可以使用 inner='quartile' 这个参数来为小提琴图添加平均数线、上四分位数线、下四分位数线。如果你想要为每一个数据都加上对应的一条线,我们可以使用 inner='stick' 参数来实现。修改后的代码如下,此时效果如下图所示。

sns.violinplot(data=df, x='星期', y='账单', inner='stick')

Seaborn 小提琴图每一个数据一条线

示例 8:曲线坡度

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单', bw_adjust=0.2)

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图曲线坡度

分析:

如果想要使用不同坡度的曲线来表示数据的分布情况,我们可以使用 bw_adjust 这个参数来实现。一般来说,当 bw_adjust 的值小于 1 时,表示使用较少平滑的曲线来表示,此时数据分布表示得更加精准。当 bw_adjust 的值大于 1 时,表示使用较多平滑的曲线来表示,此时数据分布表示得更加曲略。

小提琴图中的 bw_adjust 参数,和核密度图中的 bw_adjust 参数的功能是一样的。小伙伴们可以对比一下,这样更能加深理解和记忆。

示例 9:结合分布散点图

import matplotlib.pyplot as plt
import seaborn as sns

# 设置
sns.set_theme(rc={'font.sans-serif': 'SimHei', 'axes.unicode_minus': False})

# 加载内置数据集
df = sns.load_dataset('tips')
# 重命名列
column_map = {
    'total_bill': '账单',
    'tip': '小费',
    'sex': '性别',
    'smoker': '是否吸烟',
    'day': '星期',
    'time': '餐段',
    'size': '人数'
}
df.rename(columns=column_map, inplace=True)

# 绘制图表
sns.violinplot(data=df, x='星期', y='账单')
sns.stripplot(data=df, x='星期', y='账单', color='black')

# 显示
plt.show()

运行之后,效果如下图所示。

Seaborn 小提琴图结合分布散点图

分析:

对于小提琴图来说,我们还可以使用分布散点图把每一个数据点展示在小提琴图上。其中,stripplot() 函数用于绘制一个分布散点图。对于分布散点图,我们在后续章节中会详细介绍。

最后,我们来总结一下 violinplot() 函数的参数,常用的如下表所示。

violinplot() 函数的参数
参数 说明
data 数据部分
x x 轴坐标
y y 轴坐标
hue 添加区分(颜色)
order 改变顺序
split=True 合并显示
inner='quartile' 添加百分位线
inner='stick' 每一个数据一条线
bw_adjust 曲线平滑度
给站长反馈

绿叶网正在不断完善中,小伙伴们如果发现任何问题,还望多多给站长反馈,谢谢!

邮箱:lvyenet@vip.qq.com

「绿叶网」服务号
绿叶网服务号放大
关注服务号,微信也能看教程。
绿叶网服务号