seaborn绘图

学习目标

  • 掌握seaborn的可视化绘图方法

1. seaborn 简介

seaborn 是基于 matplotlib 的图形可视化 python 包。它提供了一种高度交互式界面,便于用户能够做出各种有吸引力的统计图表。

1)seaborn 是在 matplotlib 的基础上进行了更高级的 API 封装,从而使得作图更加容易,在大多数情况下使用seaborn 能做出很具有吸引力的图,而使用 matplotlib 就能制作具有更多特色的图

2)seaborn和 pandas 的 API 配合的很好,使用 DataFrame/Series 的数据就可以绘图

1)加载 fifa.csv 数据

import pandas as pd
# index_col指定行标签索引列, parse_dates=True:解析日期数据为datetime类型
fifa_data = pd.read_csv('./data/fifa.csv', index_col='Date', parse_dates=True)
fifa_data.head()

img

2)使用 seanborn 绘制折线图

import seaborn as sns
import matplotlib.pyplot as plt
plt.figure(figsize=(16, 8))
sns.lineplot(data=fifa_data)

img

2. seaborn 单变量数据可视化

2.1 直方图

1)使用 sns.distplot 创建直方图,如下所示:

# 加载 seaborn 的自带数据
tips = sns.load_dataset('tips')
# 使用 seaborn 的 distplot 函数绘图
ax = sns.distplot(tips['total_bill'])
ax.set_title('Total Bill Histogram with Density Plot')

img

distplot 默认会同时绘制直方图和密度图(核密度估计 kde)。

核密度估计:就是采用平滑的峰值函数(“核”)来拟合观察到的数据点,从而对真实的概率分布曲线进行模拟。

如果只想绘制直方图,可以把 kde 参数设置为 False

ax = sns.distplot(tips['total_bill'], kde=False)
ax.set_xlabel('Total Bill')
ax.set_ylabel('Frequency')
ax.set_title('Total Bill Histogram')

img

2.2 密度图(核密度估计)

密度图是展示单变量分布的另一种方法,本质上是通过绘制每个数据点为中心的正态分布,然后消除重叠的图,使曲线下的面积为1来创建的

ax = sns.distplot(tips['total_bill'], hist=False)
ax.set_xlabel('Total Bill')
ax.set_ylabel('Density')
ax.set_title('Total Bill Histogram')

img

如果只绘制密度图,还可以使用sns.kdeplot函数

2.3 频数图

频数图是变量分布的一维表示,常与其他图一起使用,以增强可视化效果。

1)下图展示的是带密度图和频数图的直方图

ax = sns.distplot(tips['total_bill'], rug=True)
ax.set_title('Total Bill Histogram with Density and Rug Plot')
ax.set_xlabel('Total Bill')

img

2.4 计数图(条形图)

计数图和直方图很像,直方图通过对数据分组来描述分布。计数图(条形图)是对离散变量(分类变量)计数

ax = sns.countplot(x='day', data=tips)
ax.set_title('Count of days')
ax.set_xlabel('Day of the Week')
ax.set_ylabel('Frequency')

img

3. seaborn 双变量数据可视化

3.1 散点图

在 seaborn 中,创建散点图的方法有很多,但是并没有名为 scatter 的函数。

创建散点图可以使用 regplot 函数。regplot 不仅可以绘制散点图,还会拟合回归线,把 fit_reg 设置为False,将只显示散点图

ax = sns.regplot(x='total_bill',y='tip',data=tips)
ax.set_title('Scatterplot of Total Bill and Tip')
ax.set_xlabel('Total Bill')
ax.set_ylabel('Tip')

img

lmplot函数和regplot函数类似,也可以用于创建散点图:

lmplot函数内部会调用regplot,两者的主要区别是regplot创建坐标轴,而lmplot创建图

fig = sns.lmplot(x='total_bill', y='tip', data=tips)

img

还可以使用jointplot在每个轴上创建包含单个变量直方图的散点图:

joint = sns.jointplot(x='total_bill', y='tip', data=tips)
joint.set_axis_labels(xlabel='Total Bill', ylabel='Tip')
# 添加标题,设置字号
# 移动轴域上方的文字
joint.fig.suptitle('Joint Plot of Total Bill and Tip', fontsize=10, y=1.03)

img

3.2 蜂巢图

使用 seaborn 的jointplot绘制蜂巢图,和使用 Matplotlib 的 hexbin 函数进行绘制的效果类似

joint = sns.jointplot(x='total_bill', y='tip', data=tips, kind='hex')
joint.set_axis_labels(xlabel='Total Bill', ylabel='Tip')
joint.fig.suptitle('Hexbin Joint Plot of Total Bill and Tip', fontsize=10, y=1.03)

img

3.3 2D 密度图

2D 核密度图和distplot类似,但2D核密度图可展示两个变量

# shade:是否填充轮廓,默认为False
ax = sns.kdeplot(data=tips['total_bill'], data2=tips['tip'], shade=True)
ax.set_title('Kernel Density Plot of Total Bill and Tip')
ax.set_xlabel('Total Bill')
ax.set_ylabel('Tip')

img

ax = sns.kdeplot(data=tips['total_bill'], data2=tips['tip'])
ax.set_title('Kernel Density Plot of Total Bill and Tip')
ax.set_xlabel('Total Bill')
ax.set_ylabel('Tip')

img

kde_joint = sns.jointplot(x='total_bill', y='tip', data=tips, shade=True, kind='kde')

img

3.4 条形图

条形图也可以用于展现多个变量,barplot 默认会计算平均值

ax = sns.barplot(x='time', y='total_bill', data=tips) 
ax.set_title('Bar plot of average total bill for time of day')
ax.set_xlabel('Time of day')
ax.set_ylabel('Average total bill')

img

3.5 箱线图

箱线图用于显示多种统计信息:最小值、1/4分位、中位数、3/4分位、最大值,以及离群值(如果有)

ax = sns.boxplot(x='time', y='total_bill', data=tips)
ax.set_title('Boxplot of total bill by time of day')
ax.set_xlabel('Time of day')
ax.set_ylabel('Total Bill')

img

3.6 小提琴图

箱线图是经典的可视化方法,但可能会掩盖数据的分布,小提琴图能显示与箱线图相同的值

小提琴图把"箱线"绘成核密度估计,有助于保留数据的更多可视化信息

ax = sns.violinplot(x='time', y='total_bill', data=tips)
ax.set_title('Violin plot of total bill by time of day')
ax.set_xlabel('Time of day')
ax.set_ylabel('Total Bill')

img

3.7 成对关系

当大部分数据是数值时,可以使用pairplot函数把所有成对关系绘制出来

pairplot 函数会为单变量绘制直方图,双变量绘制散点图:

fig = sns.pairplot(tips)

img

pairplot 的缺点是存在冗余信息,图的上半部分和下半部分相同

可以使用pairgrid手动指定图的上半部分和下半部分:

pair_grid = sns.PairGrid(tips)
pair_grid.map_upper(sns.regplot)
pair_grid.map_lower(sns.kdeplot, shade=True)
pair_grid.map_diag(sns.histplot, kde=True)
pair_grid.map_diag(sns.rugplot)

img

4. seaborn 多变量数据可视化

绘制多变量数据没有标准的套路,如果想在图中包含更多信息,可以使用颜色、大小和形状来区分它们

4.1 通过颜色区分

使用violinplot函数时,可以通过hue参数按性别(sex)给图着色

可以为“小提琴”的左右两半着不同颜色,用于区分性别:

ax = sns.violinplot(x='time', y='total_bill', hue='sex', data=tips, split=True)
ax.set_title('Violin plot of total bill by time of day')
ax.set_xlabel('Time of day')
ax.set_ylabel('Total Bill')

img

其它绘图函数中也存在hue参数:

scatter = sns.lmplot(x='total_bill', y='tip', 
                     data=tips, hue='sex', fit_reg=False)

img

通过向hue参数传入一个类别变量,可以让pairplot变得更有意义:

fig = sns.pairplot(tips, hue='sex')

img

4.2 通过大小和形状区分

可以通过点的大小表示更多信息,但通过大小区分应谨慎使用,当大小差别不大时很难区分

在 seaborn 中的lmplot,可以通过scatter_kws参数来控制散点图点的大小:

scatter = sns.lmplot(x='total_bill', y='tip', data=tips, 
                     fit_reg=False, hue='sex', markers=['o','x'])

img

4.3 分面

同一张二维图形中能展示的信息有限,如果想展示更多变量,可以使用分面(facet)来满足这些需求

1)使用 seaborn 的 lmplot函数重新绘制 anscombe 数据

anscombe = sns.load_dataset('anscombe')
# col:用于指定分面变量 这里指定 'dataset' 列中,每个取值创建一张散点图
# col_wrap:用于指定绘制的图形有几列
anscombe_plot = sns.lmplot(x = 'x', y='y', data=anscombe, 
                           fit_reg=False, col='dataset', col_wrap=2)

img

注意:lmplot函数返回的是figure(图),但regplot函数返回的是 axes(坐标系),只有返回 figure 的函数,才有 col 和 col_wrap 参数

如果是返回 axes 的函数,必须先创建 FacetGrid,通过 FacetGrid 创建分面:

facet = sns.FacetGrid(tips, col='time', size=5)
facet.map(sns.distplot, 'total_bill', rug=True)

img

FacetGrid 中绘图可以直接调用 Matplotlib 中的绘图方法:

facet = sns.FacetGrid(data=tips, col='day', hue='sex', height=5, col_wrap=2)
facet.map(plt.scatter, 'total_bill', 'tip')
facet.add_legend()

img

相同的效果也可以使用 seaborn 的 lmplot 实现:

fig = sns.lmplot(x='total_bill', y='tip', data=tips, 
                 fit_reg=False, hue='sex', col='day', col_wrap=2)

img

5. seaborn 主题和样式

上面的 seaborn 图都采用了默认样式,可以使用 sns.set_style 函数更改样式。

该函数只要运行一次,后续绘图的样式都会发生变化。

seaborn 有 5 种样式:

  • darkgrid 黑色网格(默认)
  • whitegrid 白色网格
  • dark 黑色背景
  • white 白色背景
  • ticks
ax = sns.violinplot(x='time', y='total_bill', hue='sex',
                    data = tips, split=True)

img

sns.set_style('whitegrid')
ax = sns.violinplot(x='time', y='total_bill', hue='sex',
                    data = tips, split=True)

img

总结

  • seaborn 是对 Matplotlib 以及 pandas 的封装,与Series、DataFrame的 API 配合很好
  • seaborn的 API 非常简单
  • 推荐使用 seaborn 或 pandas 进行绘图,如果需要对图形控制比较精细,可以使用Matplotlib