使用计数图进行可视化
学习如何根据数据需求对计数图进行样式设置和自定义。
计数图用于统计每个类别的实例数量。我们使用它来展示分类数据中每个唯一类别的实例数量,以条形的形式呈现。
首先,导入所需的库和 seaborn 库中的 tips 数据集,使用 sns.load_dataset() 函数加载数据。接着,使用 pandas 的 head() 函数查看前五行数据记录,以了解数据概况。
1import pandas as pd 2import seaborn as sns 3import matplotlib.pyplot as plt 4sns.set_theme() 5tips_df = sns.load_dataset('tips') 6print(tips_df.head())
接下来,通过向 sns.countplot() 函数传递 x='sex' 来查看 tips 数据集中男性和女性顾客的比例。sns.countplot() 函数返回一个 matplotlib 坐标轴(Axes)对象,其 containers 属性中保存了绘制条形的条形容器。然后调用 bar_label() 函数为条形添加标签。该函数接收一个容器作为输入,用于在计数图的条形上添加标签。
1cplot = sns.countplot(data=tips_df, x='sex') # 返回条形容器 2plt.bar_label(cplot.containers[0]) 3plt.savefig('output/graph.png') # 保存图形
在上述示例中,我们看到不同颜色代表两个类别。但也可以通过在 sns.countplot() 函数的 color 参数中指定所需颜色,将其设置为单一颜色。我们还可以通过选择 padding=2(条形与标签之间的距离)、color='red'、fontsize=15 和 label_type='edge'(将标签显示在条形顶部)来自定义条形标签。此外,将标签放在条形上方会使图形显得拥挤,因此我们使用 ylim() 函数增加 y 轴范围。
1cplot = sns.countplot(data=tips_df, x='sex', color='green') 2plt.bar_label(cplot.containers[0], padding=2, color='red', 3 fontsize=15, label_type='edge') # 自定义条形标签 4plt.ylim(top=180) # 自定义坐标轴范围 5plt.savefig('output/graph.png')
为了对计数图进行颜色编码,我们在 sns.countplot() 函数中传递 hue 参数。如图所示,我们根据是否吸烟对男女顾客进行了分类。可以看出,男性吸烟者的数量高于女性吸烟者。此外,由于这是一个分组计数图,每根条形中有两个组,因此需要两次调用 bar_label() 函数。我们为第一组(吸烟者)在条形顶部显示红色标签,为第二组(非吸烟者)在条形中心显示黑色标签。
1c_plot = sns.countplot(data=tips_df, x='sex', hue='smoker') 2plt.bar_label(c_plot.containers[0], padding=1, color='red', 3 fontsize=15, label_type='edge') # 第一组 4plt.bar_label(c_plot.containers[1], padding=1, color='black', 5 fontsize=15, label_type='center') # 第二组 6plt.ylim(top=120) 7plt.savefig('output/graph.png')
为进一步可视化,我们可以导入 penguins 数据集并将其存储在 penguins_df 数据框中。首先,使用 sns.set() 函数减小字体大小,以便在图表上完整显示物种名称。接着,为了将计数图的方向从垂直改为水平,我们将 species 列传递给 sns.countplot() 函数的 y 参数。我们还可以自定义条形标签,因为这是一个水平图表。为此,可以使用 xlim() 函数增加 x 轴范围,使标签和条形都能完整显示在图形内。
1penguins_df = sns.load_dataset('penguins') 2sns.set(font_scale=0.9) 3c_plot = sns.countplot(y='species', data=penguins_df) 4plt.bar_label(c_plot.containers[0], padding=1, color='black', 5 fontsize=12, label_type='edge') 6plt.xlim(right=170) # 设置水平图的 xlim 7plt.savefig('output/graph.png')
在计数图中,我们统计每个分类列的实例数量。我们可以通过 pandas 函数验证这一点,如下代码所示。我们访问数据框中的 species 列并对其调用 value_counts() 函数。我们可以看到每个唯一类别的数量在计数图中被精确映射。
1print(penguins_df.species.value_counts())
我们可以通过在 sns.countplot() 函数的 order 参数中指定所需的顺序来改变计数图中不同类别的显示顺序。例如,我们传入 order=['Adelie','Gentoo','Chinstrap']。第一根条形代表 Adelie 物种,第二根条形代表 Gentoo 物种,依此类推。我们还可以调用 bar_label() 函数来自定义条形标签。
1c_plot = sns.countplot(x='species', data=penguins_df, 2 order=['Adelie','Gentoo','Chinstrap']) 3plt.bar_label(c_plot.containers[0], padding=1, color='red', 4 fontsize=15, label_type='edge') 5plt.ylim(top=170) 6plt.savefig('output/graph.png')
类似地,我们可以使用 hue_order 参数指定颜色编码类别的显示顺序。我们可以在参数中指定任意 hue 类别的顺序,或限制要进行颜色编码的类别数量。例如,在下面的图表中,我们仅使用 island 变量的两个值而非三个:
1c_plot = sns.countplot(x='species', data=penguins_df, 2 hue='island', hue_order=['Torgersen','Dream']) 3plt.bar_label(c_plot.containers[0], padding=1, color='black', 4 fontsize=15, label_type='edge') # 第一组 5plt.bar_label(c_plot.containers[1], padding=1, color='black', 6 fontsize=15, label_type='edge') # 第二组 7plt.ylim(top=100) 8plt.savefig('output/graph.png')
我们可以通过 pandas 库验证这一点,如下代码所示。首先,我们按 species 分组,然后访问 island 列并调用 value_counts() 函数,以显示每个类别的计数。我们可以看到,Gentoo 物种仅出现在 Biscoe 岛上。正如计数图所示,我们没有看到 Gentoo 物种的条形。
1print(penguins_df.groupby('species').island.value_counts())
我们可以使用 sns.countplot() 函数中的 saturation 参数来美化我们的计数图。饱和度越低,图形颜色越暗淡;饱和度越高,图形颜色越明亮。在下面的计数图中,我们在 sns.countplot() 函数中指定 saturation=0.4,图形的颜色较为暗淡。
1c_plot = sns.countplot(data=tips_df, x='sex', hue='time', saturation=0.4) 2plt.bar_label(c_plot.containers[0], padding=1, color='black', 3 fontsize=15, label_type='edge') # 第一组 4plt.bar_label(c_plot.containers[1], padding=1, color='red', 5 fontsize=15, label_type='edge') # 第二组 6plt.ylim(top=140) # 设置 y 轴限制 7plt.savefig('output/graph.png')
类似地,在下面的计数图中,我们在 sns.countplot() 函数中指定 saturation=3.0。结果,图形的颜色非常明亮。
1c_plot = sns.countplot(data=tips_df, x='sex', hue='time', saturation=3.0) 2plt.bar_label(c_plot.containers[0], padding=1, color='black', 3 fontsize=15, label_type='edge') # 第一组 4plt.bar_label(c_plot.containers[1], padding=1, color='red', 5 fontsize=15, label_type='edge') # 第二组 6plt.ylim(top=140) 7plt.savefig('output/graph.png')