相关性

seaborn + matplotlib 画图(一): 小提琴图

2021-03-26  本文已影响0人  WuYankang

Seaborn 是一个基于 matplotlib 且数据结构与 pandas 统一的统计图制作库

前段时间有一些作图需求,处理数据用的又是pandas,于是就发现了Seaborn这个作图的好工具。之前的代码在Jupyter notebook里,比较分散又没有整理,平时也记不住这么多函数和参数,想想还是整理一下分享出来,即方便自己查看,也能帮助有需要的人。
另外,在写这篇文章的时候发现了Seaborn的中文文档,相见恨晚啊,向翻译大大们致敬。链接贴到下面了,有空了要好好学习学习。
Seaborn 中文文档:https://seaborn.apachecn.org/#/README

seaborn + matplotlib 画图(一): 小提琴图,箱型图
seaborn + matplotlib 画图(二): 柱状图,散点图
seaborn + matplotlib 画图(三): 热图

这篇文章中使用Iris数据集作为示例,提供一些简单图形的绘制方法,下面正式开始。

1. 导入所需包

主要用到的包有numpy,pandas,matplotlib 和 seaborn

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

2. 载入Iris数据

df = pd.read_csv('http://archive.ics.uci.edu/ml/machine-learning-databases/iris/iris.data', header=None)
df.columns = ['sepal_length','sepal_width','petal_length','petal_width','class']
print(df.shape)
print(df.head())
print(df['class'].value_counts())

-----outputs-----
(150, 5)

   sepal_length  sepal_width  petal_length  petal_width        class
0           5.1          3.5           1.4          0.2  Iris-setosa
1           4.9          3.0           1.4          0.2  Iris-setosa
2           4.7          3.2           1.3          0.2  Iris-setosa
3           4.6          3.1           1.5          0.2  Iris-setosa
4           5.0          3.6           1.4          0.2  Iris-setosa

Iris-virginica     50
Iris-setosa        50
Iris-versicolor    50
Name: class, dtype: int64

Iris数据集为 150行 5列,每一行为一个观测对象,前4列分别是 sepal_length(花萼长度),sepal_width (花萼宽度),petal_length(花瓣长度),petal_width(花瓣宽度)。最后一列为class类别。共三类(Iris-virginica,Iris-setosa,Iris-versicolor),每类各50条记录。

3. 颜色和marker类型

这里贴了3个网站,是matplotlib预设的颜色和marker,方便我们选择颜色和marker形状。
Named colors: https://matplotlib.org/stable/gallery/color/named_colors.html
Colormaps: https://matplotlib.org/stable/tutorials/colors/colormaps.html
Markers: https://matplotlib.org/stable/api/markers_api.html
这里我先为3种不同的鸢尾花指定3种颜色,存放到字典里,方便后面使用。选择的颜色都是named colors里预设的。
另外,用一个列表存储3种鸢尾花的绘图顺序。

pal = {'Iris-setosa':'lightcoral','Iris-versicolor':'navajowhite','Iris-virginica':'cornflowerblue'}
class_order = ['Iris-setosa','Iris-versicolor','Iris-virginica']

4. violinplot小提琴图

首先使用violinplot()画一个简单的小提琴图。

plt.figure(figsize=(5,5))        #定义图像大小
g = sns.violinplot(data=df, x='class', y='sepal_length',         #传入数据,对sepal_length这一列画图,根据class分组
                   linewidth=3,        #线宽
                   inner='box',        #内部数据形式,默认为box,内部画个小箱型图            
                   palette=pal,        #指定颜色盘绘制不同颜色,若使用color参数,则统一设置为一种颜色
                   order=class_order,        #指定顺序
                   saturation=1)        #色彩饱和度,默认0.75
plt.show()
violinplot

虽然还行,不过还需要一些修改,比如轴标签有下划线,字体太小,想去掉上框线和右框线。

plt.figure(figsize=(5,5))
g = sns.violinplot(data=df, x='class', y='sepal_length', linewidth=3,
                   inner='box', palette=pal, order=class_order, saturation=1)

ylabel = 'Sepal length'
plt.ylabel(ylabel, fontsize=18)        #设置y轴标签
plt.yticks(fontsize=15)        #设置y轴刻度字体大小
plt.xlabel('')        #去掉x轴标签
plt.xticks(ticks=[0,1,2],        #设置要显示的x轴刻度,若指定空列表则去掉x轴刻度
           labels=['Setosa','Versicolor','Virginiical'],        #设置x轴刻度显示的文字,要与ticks对应   
           fontsize=15,        #设置刻度字体大小
           rotation=60,        #设置刻度文字旋转角度
           ha='right', va='center',        #刻度文字对齐方式,当rotation_mode为’anchor'时,对齐方式决定了文字旋转的中心。ha也可以写成horizontalalignment,va也可以写成verticalalignment。
           rotation_mode='anchor')        #我的设置表示文字以右边线的中点为中心旋转。

ax = plt.axes()
ax.spines['top'].set_visible(False)        #去掉图像上边框和右边框
ax.spines['right'].set_visible(False)

plt.show()
violinplot

看起来还不错,但如果想要知道每个点的具体情况呢?不如把所有的点也画上去吧。swarmplot()看起来非常合适。

plt.figure(figsize=(5,5))
g1 = sns.violinplot(data=df, x='class', y='sepal_length', linewidth=3,
                   inner='box', palette=pal, order=class_order, saturation=1)
ylabel = 'Sepal length'
plt.ylabel(ylabel, fontsize=18)
plt.yticks(fontsize=15)
plt.xlabel('')
plt.xticks(ticks=[0,1,2], labels=['Setosa','Versicolor','Virginiical'],
           fontsize=15, rotation=60, ha='right', va='center', rotation_mode='anchor')
ax = plt.axes()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

g2 = sns.swarmplot(data=df, x='class', y='sepal_length',
                   color='grey', alpha=0.5, size=4,        #颜色,透明度,大小
                   linewidth=0.5, edgecolor='black',        #边线宽度,边线颜色
                   order=class_order)        #顺序和violinplot保持一致

plt.show()
violinplot

5. boxplot箱型图

单独的箱型图

plt.figure(figsize=(5,5))
g = sns.boxplot(data=df, x='class', y='sepal_length',        #传入数据
                linewidth=3,        #箱边线宽度
                width=0.8,        #箱体宽度,默认0.8
                whis=1.5        #计算上限和下限时四分位距(IQR)前的系数,默认1.5
                showfliers=True,        #是否显示异常值
                fliersize=5,        #异常值大小,默认5
                palette=pal,        #颜色盘
                order=class_order,        #顺序
                saturation=1)        #颜色饱和度,默认0.75

ylabel = 'Sepal length'
plt.ylabel(ylabel, fontsize=18)
plt.yticks(fontsize=15)
plt.xlabel('')
plt.xticks(ticks=[0,1,2], labels=['Setosa','Versicolor','Virginiical'],
           fontsize=15, ha='center', va='top')
ax = plt.axes()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.show()
boxplot

这里顺便对箱型图做个介绍:
箱体(有颜色的部分)上边缘:上四分位数,Q3
箱体下边缘:下四分位数,Q1
箱体中线:中位数
上方横线:上限范围内的最大值
下方横线:下限范围内的最小值
横线之外的点:异常值
上限计算:Q3+1.5×IQR
下限计算:Q1-1.5×IQR
IQR:四分位距 (interquartile range),IQR = Q3 - Q1

barplot + swarmplot
和小提琴图一样,我们可以在箱型图的基础上,画上散点图,这样所有数据点的分布更加直观。

plt.figure(figsize=(5,5))
g = sns.boxplot(data=df, x='class', y='sepal_length', linewidth=3, showfliers=False,
                palette=pal, order=class_order, saturation=1)


sns.swarmplot(data=df, x='class', y='sepal_length',
              color='grey', size=4, linewidth=0.5, edgecolor='k',
              order=class_order, alpha=0.75)

ylabel = 'Sepal length'
plt.ylabel(ylabel, fontsize=18)
plt.yticks(fontsize=15)
plt.xlabel('')
plt.xticks(ticks=[0,1,2], labels=['Setosa','Versicolor','Virginiical'],
           fontsize=15, ha='center', va='top')
ax = plt.axes()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.show()
barplot

空心的箱型图
有时会在一些文献中看到空心的箱型图,虽然可以通过将颜色设置成白色达到空心的效果,但是barplot()中似乎没有参数可以用来设置线的颜色,所以只能是黑色的线。好在还是有其它办法设置的。

plt.figure(figsize=(5,5))
g = sns.boxplot(data=df, x='class', y='sepal_length', linewidth=5,showfliers=False,
                order=class_order,saturation=1)
for i in range(len(g.artists)):
    box = g.artists[i]
    box.set_edgecolor(pal[class_order[i]])
    box.set_facecolor('white')
    for j in range(5):
        k = i*5 + j
        line = g.lines[k]
        line.set_color(pal[class_order[i]])

sns.swarmplot(data=df, x='class', y='sepal_length',
              color='grey', size=4, linewidth=0.5, edgecolor='k',
              order=class_order, alpha=0.75)

ylabel = 'Sepal length'
plt.ylabel(ylabel, fontsize=18)
plt.yticks(fontsize=15)
plt.xlabel('')
plt.xticks(ticks=[0,1,2], labels=['Setosa','Versicolor','Virginiical'],
           fontsize=15, ha='center', va='top')
ax = plt.axes()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.show()
barplot

其它部分基本一样,主要的不同在于添加了4~11行设置颜色的代码。
g.artists是一个列表,有3个元素(数量和箱型图的数量一样,对象类型是matplotlib.patches.PathPatch),分别是3个箱型图的箱体,通过set_edgecolor()set_facecolor()方法这是边线颜色(不包括中位线的颜色)和箱体颜色。
g.lines也是一个列表,有15个元素(对象类型是matplotlib.lines.Line2D),包含了箱体那个长方形之外的所有其它线,一个箱型图有5条线(上边线,下边线,2条垂直线,1条中位线),第i个(从0开始)箱型图的5条线index范围是[i*5+0, i*5+4],通过set_color()方法设置颜色。

下面的例子可以更清楚的看到g.lines中的每个元素所对应的线是哪条。

plt.figure(figsize=(5,5))
g = sns.boxplot(data=df, x='class', y='sepal_length', linewidth=5,showfliers=False,
              palette=pal, order=class_order,saturation=1)
for i in range(len(g.artists)):
    box = g.artists[i]
    box.set_edgecolor(pal[class_order[i]])
    box.set_facecolor('white')
    g.lines[i*5 + 0].set_color('r')
    g.lines[i*5 + 1].set_color('g')
    g.lines[i*5 + 2].set_color('b')
    g.lines[i*5 + 3].set_color('y')
    g.lines[i*5 + 4].set_color('purple')

ylabel = 'Sepal length'
plt.ylabel(ylabel, fontsize=18)
plt.yticks(fontsize=15)
plt.xlabel('')
plt.xticks(ticks=[0,1,2], labels=['Setosa','Versicolor','Virginiical'],
           fontsize=15, ha='center', va='top')
ax = plt.axes()
ax.spines['top'].set_visible(False)
ax.spines['right'].set_visible(False)

plt.show()

按照红、绿、蓝、黄、紫的顺序对g.lines中的元素设置颜色。

barplot

6. savefig保存图片

目前支持的图片格式:eps, pdf, pgf, png, ps, raw, rgba, svg, svgz。
plt.savefig() 需要放在 plt.show() 之前。

outfig = 'E:/fig.png'     #supported formats: eps, pdf, pgf, png, ps, raw, rgba, svg, svgz
plt.savefig(outfig,
            dpi=300,        # 设置分辨率
            format=None,        #设置图片格式,默认None,如果未设置使用文件名设置的格式
            bbox_inches='tight',        #设置为tight,防止有时图片保存不完整
            facecolor='w',        #背景颜色,默认'w'白色
            edgecolor='w')        #边框颜色,默认'w'白色
上一篇下一篇

猜你喜欢

热点阅读