Matplotlib和Seaborn之条形图
条形图
条形图用于描述分类变量的分布情况。在条形图中,分类变量的每个级别用长条表示,高度表示数据在该级别的出现频率。我们可以通过 seaborn 的 countplot
函数创建基本的频率条形图:
sb.countplot(data = df, x = 'cat_var')
image.png
对于给定的示例,可以看出,β 级别频率最高,超过 100 次,然后是 γ 和 α,δ 的频率最低,大约为 50。默认情况下,每个类别都用不同的颜色标注。这样的话,在这些类别标签之间建立关联性以及在图中用更多的变量编码时会比较方便。否则,建议简化图表,将所有长条都用相同的颜色标注,可以减少不必要的干扰。我们可以使用 "color" 参数设置长条颜色:
base_color = sb.color_palette()[0]
sb.countplot(data = df, x = 'cat_var', color = base_color)
color_palette
返回一个 RGB 元组列表,每个元组指定一个颜色。数字参数返回当前/默认调色板,我们将第一个颜色设为所有长条的颜色。
对于条形图,我们可能需要执行的一个操作是以某种方式对数据排序。对于名目数据,一种常见操作是按照频率对数据排序。我们的数据采用的是 pandas DataFrame,因此我们可以使用各种 DataFrame 方法来计算和得出排序方式,然后使用 "order" 参数设置排序方式:
base_color = sb.color_palette()[0]
cat_order = df['cat_var'].value_counts().index
sb.countplot(data = df, x = 'cat_var', color = base_color, order = cat_order)
image.png
对于有序数据,我们可能需要根据变量顺序对长条排序。虽然我们像上面的示例一样按照频率对级别排序,但是我们通常关心的是频率最高的值是否是很高的级别、很低的级别,等等。在这种情况下,最佳做法是将列转换为有序分类数据类型。默认情况下,pandas 将字符串数据读取为对象类型,并按照唯一值的顺序绘制长条。通过以这种方式转换数据,我们拥有针对所有图形的排序方式,而不用不断指定 "order" 参数。
# 本方法要求 pandas 0.21 或更高版本
level_order = ['Alpha', 'Beta', 'Gamma', 'Delta']
ordered_cat = pd.api.types.CategoricalDtype(ordered = True, categories = level_order)
df['cat_var'] = df['cat_var'].astype(ordered_cat)
## 如果你的 pandas 为 0.20.3 或更低版本,请使用这种方法:
# df['cat_var'] = df['cat_var'].astype('category', ordered = True,
# categories = level_order)
base_color = sb.color_palette()[0]
sb.countplot(data = df, x = 'cat_var', color = base_color)
(文档:CategoricalDtype)
image.png如果你发现你需要按照不同的顺序对有序分类数据排序,始终可以通过设置 "order" 参数临时替换数据类型,如上所示。
其他变量
如果数据是 pandas Series、一维 NumPy 数组或列表形式,你可以将其设为 countplot
函数的第一个参数,如以下 Series data_var
所示:
sb.countplot(data_var)
如果有很多个分类级别,或者类别名称很长,那么刻度标记可能会紧挨在一起。一种解决方式是创建横条图。在横条图中,每个长条的长度(而不是高度)表示频率。在代码中,你可以设置在参数 "y" 上绘制变量,而不是在参数 "x" 上绘制数据或变量:
base_color = sb.color_palette()[0]
sb.countplot(data = df, y = 'cat_var', color = base_color)
image.png
此外,你可以使用 matplotlib 的 xticks
函数及其 "rotation" 参数更改绘制标签的方向(与水平方向的逆时针夹角度数):
base_color = sb.color_palette()[0]
sb.countplot(data = df, x = 'cat_var', color = base_color)
plt.xticks(rotation = 90)
image.png