分布(三)利用python绘制箱线图

箱线图 (Boxplot)简介

1

箱线图也叫盒须图,主要用来突出显示数据分布的四分位数。同时也可以获取较多的统计信息,例如:四分位数、异常值、分布是否倾斜/对称等。

快速绘制

  1. 基于seaborn

    import seaborn as sns
    import matplotlib.pyplot as plt
    sns.set(style="darkgrid")
    
    # 导入数据
    df = sns.load_dataset('iris')
    
    # 利用boxplot函数绘制箱线图
    sns.boxplot(y=df["sepal_length"])
    plt.show()
    

    2

定制多样化的箱线图

自定义箱线图一般是结合使用场景对相关参数进行修改,并辅以其他的绘图知识。参数信息可以通过官网进行查看,其他的绘图知识则更多来源于实战经验,大家不妨将接下来的绘图作为一种学习经验,以便于日后总结。

seaborn主要利用boxplot箱线图,可以通过seaborn.boxplot了解更多用法

  1. 绘制多个箱线图

    import seaborn as sns
    import matplotlib.pyplot as plt
    
    sns.set(font='SimHei', font_scale=0.8, style="darkgrid") # 解决Seaborn中文显示问题
    
    # 导入数据
    df = sns.load_dataset('iris')
    df_tips = sns.load_dataset('tips')
    
    # 创建matplotlib的fig对象和子图对象ax
    fig, ax = plt.subplots(1,3, figsize=(12,4))
    
    # 多个数值变量的箱线图
    sns.boxplot(data=df.loc[:, ['sepal_length', 'sepal_width']], ax=ax[0]) 
    ax[0].set_title('多个数值变量')
    
    # 一个数值变量多个分组的箱线图
    sns.boxplot(x=df["species"], y=df["sepal_length"], ax=ax[1])
    ax[1].set_title('一个数值变量多个分组')
    
    # 一个数值变量多个分组子分组的箱线图
    sns.boxplot(x="day", y="total_bill", hue="smoker", data=df_tips, palette="Set1", width=0.5, ax=ax[2])
    ax[2].set_title('一个数值变量多个分组/子分组')
    
    # 调整间距并展示
    plt.tight_layout()
    plt.show()
    

    3

  2. 自定义箱线图

    • 自定义形状
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    sns.set(font='SimHei', font_scale=0.8, style="darkgrid") # 解决Seaborn中文显示问题
    
    # 导入数据
    df = sns.load_dataset('iris')
    
    # 构造子图
    fig, ax = plt.subplots(1,3,constrained_layout=True, figsize=(12, 4))
    
    # 自定义线宽
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], linewidth=5, ax=ax[0])
    ax_sub.set_title('自定义线宽')
    
    # 添加缺口
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], notch=True, ax=ax[1])
    ax_sub.set_title('添加缺口')
    
    # 自定义箱体
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], width=0.3, ax=ax[2])
    ax_sub.set_title('自定义箱体大小')
    
    plt.show()
    

    4

    • 自定义颜色
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    sns.set(font='SimHei', font_scale=0.8, style="darkgrid") # 解决Seaborn中文显示问题
    
    # 导入数据
    df = sns.load_dataset('iris')
    
    # 构造子图
    fig, ax = plt.subplots(1,4,constrained_layout=True, figsize=(12, 4))
    
    # 分配调色板
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], palette="Blues", ax=ax[0])
    ax_sub.set_title('分配调色板')
    
    # 统一颜色
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], color='skyblue', ax=ax[1])
    ax_sub.set_title('统一颜色')
    
    # 自定义颜色
    my_pal = {"versicolor": "g", "setosa": "b", "virginica":"m"}
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], palette=my_pal, ax=ax[2])
    ax_sub.set_title('指定颜色')
    
    # 突出颜色:针对指定组
    my_pal = {species: "r" if species == "versicolor" else "b" for species in df.species.unique()}
    ax_sub = sns.boxplot(x=df["species"], y=df["sepal_length"], palette=my_pal, ax=ax[3])
    ax_sub.set_title('突出颜色')
    
    plt.show()
    

    5

    • 自定义顺序
    import seaborn as sns
    import matplotlib.pyplot as plt
    
    sns.set(font='SimHei', font_scale=0.8, style="darkgrid") # 解决Seaborn中文显示问题
    
    # 导入数据
    df = sns.load_dataset('iris')
    
    # 构造子图
    fig, ax = plt.subplots(1,2,constrained_layout=True, figsize=(8, 4))
    
    # 指定顺序
    ax_sub = sns.boxplot(x='species', y='sepal_length', data=df, order=["versicolor", "virginica", "setosa"], ax=ax[0])
    ax_sub.set_title('指定顺序')
    
    # 按统计量降序:中位数
    my_order = df.groupby(by=["species"])["sepal_length"].median().iloc[::-1].index
    ax_sub = sns.boxplot(x='species', y='sepal_length', data=df, order=my_order, ax=ax[1])
    ax_sub.set_title('中位数降序')
    
    plt.show()
    

    6

  3. 添加额外数据信息

import seaborn as sns
import matplotlib.pyplot as plt

sns.set(font='SimHei', font_scale=0.8, style="darkgrid") # 解决Seaborn中文显示问题

# 导入数据
df = sns.load_dataset('iris')

# 构造子图
fig, ax = plt.subplots(1,2,constrained_layout=True, figsize=(8, 4))

# 1、添加数据点分布
ax_sub = sns.boxplot(x='species', y='sepal_length', data=df, ax=ax[0])
ax_sub = sns.swarmplot(x='species', y='sepal_length', data=df, color="grey", ax=ax[0])
ax_sub.set_title('添加数据点分布')

# 2、添加观测数量(避免过多信息造成视觉影响)
ax_sub = sns.boxplot(x='species', y='sepal_length', data=df, ax=ax[1])

medians = df.groupby(['species'])['sepal_length'].median().values
nobs = df['species'].value_counts().values
nobs = [str(x) for x in nobs.tolist()]
nobs = ["n: " + i for i in nobs]

pos = range(len(nobs))
for tick,label in zip(pos,ax_sub.get_xticklabels()):
    ax_sub.text(pos[tick],
            medians[tick] + 0.03,
            nobs[tick],
            horizontalalignment='center',
            size='x-small',
            color='w',
            weight='semibold')
ax_sub.set_title('添加观测数量')

plt.show()

7

总结

以上通过seaborn的boxplot可以快速绘制箱线图,并通过修改参数或者辅以其他绘图知识自定义各种各样的箱线图来适应相关使用场景。

共勉~

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐