Seaborn学习笔记
Seaborn简介
Seaborn
是一种基于matplotlib
的图形可视化python库。它提供了一种高度交互式界面,便于用户能够做出各种有吸引力的统计图表。Seaborn
其实是在matplotlib
的基础上进行了更高级的API封装,从而使得作图更加容易,在大多数情况下使用Seaborn
就能做出很具有吸引力的图,而使用matplotlib
就能制作具有更多特色的图。应该把Seaborn
视为matplotlib
的补充,而不是替代物。同时它能高度兼容numpy
与pandas
数据结构以及scipy
与statsmodels
等统计模式。掌握Seaborn
能很大程度帮助我们更高效的观察数据与图表,并且更加深入了解它们。
其有如下特点:
- 基于matplotlib aesthetics绘图风格,增加了一些绘图模式
- 增加调色板功能,利用色彩丰富的图像揭示您数据中的模式
- 运用数据子集绘制与比较单变量和双变量分布的功能
- 运用聚类算法可视化矩阵数据
- 灵活运用处理时间序列数据
- 利用网格建立复杂图像集
Seaborn样式
matplotlib与seaborn绘图比较
1 | import seaborn as sns |
1 | def sinplot(flip=1): |
1 | sinplot() #采用matplotlib绘制 |
1 | sns.set() #采用seaborn默认设置 |
Seaborn 5种主题风格
- darkgrid
- whitegrid
- dark
- white
- ticks
1 | sns.set_style("darkgrid") |
1 | sns.set_style("whitegrid") |
1 | sns.set_style("dark") |
1 | sns.set_style("white") |
1 | sns.set_style("ticks") |
用despine()移除轴线
样式white
和ticks
都可以通过去除上方和右方不必要的轴线来得到改善. 而这些是不可能在matplotlib
里设置参数做到的,但是你可以调用seaborn的函数despine()
来去除轴线:
1 | sns.set_style("ticks") |
有些布局也可以通过调整轴线距数据的偏移来改善,这也能在despine()里完成.当ticks不能覆盖轴线的整个范围时,trim参数可以限制显示的轴线的范围.
1 | data = np.random.normal(size=(20, 6)) + np.arange(6) / 2 # (20, 6) 二维数据 |
你也可能通过设置另外的参数来控制移除哪条轴线:
1 | sns.set_style("whitegrid") |
临时设置图表样式
尽管来回切换样式是很简单的,但是你也可以在with
语句里用axes_style()
函数来临时设置控制布局的参数.这也允许你用不同的风格来制作图表,这是一种常见的编程模式,使得控制样式和风格能够多变。
1 | with sns.axes_style("darkgrid"): |
重载seaborn样式的元素
如果你想要自定义seaborn
的样式,你可以用词典(dictionary
)将一系列控制参数赋值给axes_style()
函数和set_style()
函数的rc
参数里. 注意你只能通过这种方式重载样式定义的部分.(但是,更高级的set()
函数可以处理包含任意matplotlib
参数的词典)
如果你想要知道都包含了哪些参数,你可以调用没有参数的函数,它会返回当前设置:
1 | sns.axes_style() |
{'axes.axisbelow': True,
'axes.edgecolor': '.8',
'axes.facecolor': 'white',
'axes.grid': True,
'axes.labelcolor': '.15',
'axes.linewidth': 1.0,
'figure.facecolor': 'white',
'font.family': ['sans-serif'],
'font.sans-serif': ['Arial',
'DejaVu Sans',
'Liberation Sans',
'Bitstream Vera Sans',
'sans-serif'],
'grid.color': '.8',
'grid.linestyle': '-',
'image.cmap': 'rocket',
'legend.frameon': False,
'legend.numpoints': 1,
'legend.scatterpoints': 1,
'lines.solid_capstyle': 'round',
'text.color': '.15',
'xtick.color': '.15',
'xtick.direction': 'out',
'xtick.major.size': 0.0,
'xtick.minor.size': 0.0,
'ytick.color': '.15',
'ytick.direction': 'out',
'ytick.major.size': 0.0,
'ytick.minor.size': 0.0}
然后你可以设置这些参数的不同版本:
1 | sns.set_style("darkgrid", {"axes.facecolor": ".9"}) |
使用plotting_context()
和set_context()
设置布局元素的规模
布局元素的规模被独立的参数集合控制,这能让你使用相同的代码得到不同大小的规模合适的布局
首先让我们重新调用set()
函数得到缺省设置:
1 | sns.set() |
有4种预设好的上下文(context),按相对大小排序分别是:paper
, notebook
, talk
,和poster
.缺省的规模是notebook
,上述的所有图表都是它.
1 | sns.set_context("paper") |
1 | sns.set_context("talk") |
1 | sns.set_context("poster") |
大部分你现在所稽首的样式函数都应该被转换成上下文函数.
你可以调用set_context()
,将上下文的名字当作一个参数传入,然后你就可以通过提供一个写有各项设置值的词典重载上下文的参数。
在修改上下文时,你也可以单独修改字体大小。(更高级的set()
里也可以这么做)
1 | sns.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 2.5}) |
Seaborn配色方案
配色是图表设计里最重要的方面之一,因为如果配色方案好,它可以清晰展现数据的模式和规律,否则就会把这些规律和模式隐藏起来。Seaborn
让选择和使用配色方案变得简单且适用于你工作的数据种类和你想要达到的可视化目标。
1 | import numpy as np |
调色板
- 颜色很重要
- color_palette()能传入任何Matplotlib所支持的颜色
- color_palette()不写参数则默认颜色
- set_palette()设置所有图的颜色
分类色板
1 | current_palette = sns.color_palette() |
6个默认的颜色循环主题: deep
, muted
, pastel
, bright
, dark
, colorblind
.
圆形画板
当你有六个以上的分类要区分时,最简单的方法就是在一个圆形的颜色空间中画出均匀间隔的颜色(这样的色调会保持亮度和饱和度不变)。这是大多数的当他们需要使用比当前默认颜色循环中设置的颜色更多时的默认方案。
最常用的方法是使用hls
的颜色空间,这是RGB
值的一个简单转换。
1 | sns.palplot(sns.color_palette("hls", 8)) |
1 | #应用调色板 |
<matplotlib.axes._subplots.AxesSubplot at 0x1a1f2bc978>
hls_palette()
函数来控制颜色的亮度和饱和
- l-亮度 lightness
- s-饱和 saturation
1 | sns.palplot(sns.hls_palette(8, l=.7, s=.9)) |
1 | sns.palplot(sns.color_palette("Paired",8)) |
使用xkcd颜色自定义调色板
xkcd
包含了一套众包努力的针对随机RGB
色的命名。产生了954个可以随时通过xdcd_rgb
字典中调用的命名颜色。
可以通过sns.xkcd_rgb
进行查看。
1 | plt.plot([0, 1], [0, 1], sns.xkcd_rgb["pale red"], lw=3) |
[<matplotlib.lines.Line2D at 0x1a1f3264e0>]
1 | colors = ["windows blue", "amber", "greyish", "faded green", "dusty purple"] |
连续色板
色彩随数据变换,比如数据越来越重要则颜色越来越深
1 | sns.palplot(sns.color_palette("Blues")) |
如果想要翻转渐变,可以在面板名称中添加一个_r后缀
1 | sns.palplot(sns.color_palette("BuGn_r")) |
cubehelix_palette()
调色板
色调线性变换
1 | sns.palplot(sns.color_palette("cubehelix", 8)) |
1 | sns.palplot(sns.cubehelix_palette(8, start=.5, rot=-.75)) |
1 | sns.palplot(sns.cubehelix_palette(8, start=1.75, rot=-.150)) |
light_palette()
和dark_palette()
调用定制连续调色板
1 | sns.palplot(sns.light_palette("green")) |
1 | sns.palplot(sns.dark_palette("purple")) |
1 | sns.palplot(sns.light_palette("navy", reverse=True)) #渐变翻转 |
1 | #应用调色板 |
<matplotlib.axes._subplots.AxesSubplot at 0x1a1f1c59b0>
Seaborn变量分析绘图
1 | %matplotlib inline |
使用sns.distplot()
函数画直方图
1 | x = np.random.normal(size=100) |
<matplotlib.axes._subplots.AxesSubplot at 0x1a1fb2a240>
你也可以通过bins自己划分直方图的切分粒度
1 | sns.distplot(x, bins=20, kde=False) |
<matplotlib.axes._subplots.AxesSubplot at 0x1a202ebdd8>
通过fit
查看数据分布的情况
1 | x = np.random.gamma(6, size=200) |
<matplotlib.axes._subplots.AxesSubplot at 0x1a204df5f8>
使用jointplot()
函数绘制散点图
观测两个变量之间的分布关系最好用散点图
1 | #生成数据 |
x y
0 0.585042 1.162682
1 0.722117 2.141580
2 0.120990 0.498821
3 -0.795773 2.085261
4 -0.614260 2.215906
1 | sns.jointplot(x="x", y="y", data=df) |
<seaborn.axisgrid.JointGrid at 0x1a206a5b00>
通过kind="hex"
使散点图具备透视性,更加容易查看数据的散点分布密度情况
1 | x, y = np.random.multivariate_normal(mean, cov, 1000).T |
使用pairplot()
函数绘制关系图
两不同变量比较绘制散点图,变量自身比较绘制直方图
1 | iris = sns.load_dataset("iris") #载入鸢尾花数据集 |
<seaborn.axisgrid.PairGrid at 0x1a20ef4588>
Seaborn回归分析绘图
1 | %matplotlib inline |
1 | import seaborn as sns |
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
regplot()
绘制回归关系图
1 | #采用regplot绘制拟合的数据线 |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8d8db518>
lmplot()
绘制回归关系图
lmplot
是一种集合基础绘图与基于数据建立回归模型的绘图方法。旨在创建一个方便拟合数据集回归模型的绘图方法,利用hue
、col
、row
参数来控制绘图变量。
1 | seaborn.lmplot(x, y, data, hue=None, col=None, row=None, palette=None, col_wrap=None, size=5, aspect=1, markers='o', sharex=True, sharey=True, hue_order=None, col_order=None, row_order=None, legend=True, legend_out=True, x_estimator=None, x_bins=None, x_ci='ci', scatter=True, fit_reg=True, ci=95, n_boot=1000, units=None, order=1, logistic=False, lowess=False, robust=False, logx=False, x_partial=None, y_partial=None, truncate=False, x_jitter=None, y_jitter=None, scatter_kws=None, line_kws=None) |
参数说明:
- hue, col, row : strings #定义数据子集的变量,并在不同的图像子集中绘制
- size : scalar, optional #定义子图的高度
- markers : matplotlib marker code or list of marker codes, optional #定义散点的图标
- col_wrap : int, optional #设置每行子图数量
- order : int, optional #多项式回归,设定指数
- logistic : bool, optional #逻辑回归
- logx : bool, optional #转化为log(x)
1 | #研究小费tips与总消费金额total_bill在吸烟与不吸烟人之间的关系 |
1 | #研究在不同星期下,消费总额与消费的回归关系 |
1 | pokemon=pd.read_csv('../dataset/Pokemon.csv') #载入宠物小精灵战斗力数据集 |
# | Name | Type 1 | Type 2 | Total | HP | Attack | Defense | Sp. Atk | Sp. Def | Speed | Generation | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|
0 | 1 | Bulbasaur | Grass | Poison | 318 | 45 | 49 | 49 | 65 | 65 | 45 | 1 | False |
1 | 2 | Ivysaur | Grass | Poison | 405 | 60 | 62 | 63 | 80 | 80 | 60 | 1 | False |
2 | 3 | Venusaur | Grass | Poison | 525 | 80 | 82 | 83 | 100 | 100 | 80 | 1 | False |
3 | 3 | VenusaurMega Venusaur | Grass | Poison | 625 | 80 | 100 | 123 | 122 | 120 | 80 | 1 | False |
4 | 4 | Charmander | Fire | NaN | 309 | 39 | 52 | 43 | 60 | 50 | 65 | 1 | False |
1 | #观察每一代攻击与防御的分布,利用二次多项式逼近 |
<seaborn.axisgrid.FacetGrid at 0x22d8bce32e8>
1 | #继续在同一图中观察不同代的sp.Atk,Sp.Def线性关系 |
<seaborn.axisgrid.FacetGrid at 0x22d8be4b5f8>
Seaborn分类分析绘图
1 | %matplotlib inline |
1 | np.random.seed(sum(map(ord, "categorical"))) |
散点图
1 | sns.stripplot(x="day", y="total_bill", data=tips) |
问题:有重叠,无法看见数据的密度。
- 解决方法一:通过
jitter
抖动
抖动是平时可视化中的常用的观察“密度”的方法,除了使用参数抖动,特定的抖动需求也可以用numpy在数据上处理实现
1 | sns.stripplot(x="day", y="total_bill", data=tips, jitter=True) # jitter抖动 |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a3216a0>
- 解决方法二:通过
swarmplot()
函数
1 | sns.swarmplot(x="day", y="total_bill", data=tips) |
<matplotlib.axes._subplots.AxesSubplot at 0x22d87f3b128>
1 | sns.swarmplot(x="day", y="total_bill", hue="sex",data=tips) #hue 参数控制分组绘图 |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a428860>
箱型图
箱形图(Box-plot)又称为盒须图、盒式图或箱线图,是一种用作显示一组数据分散情况资料的统计图。因形状如箱子而得名。
如上图所示,标示了图中每条线表示的含义,其中应用到了分位值(数)的概念。
主要包含六个数据节点,将一组数据从大到小排列,分别计算出他的上边缘,上四分位数Q3,中位数,下四分位数Q1,下边缘,还有一个异常值。
举例说明,以下是箱形图的具体例子:
这组数据显示出:
- 最小值(minimum)=5
- 下四分位数(Q1)=7
- 中位数(Med–也就是Q2)=8.5
- 上四分位数(Q3)=9
- 最大值(maximum)=10
- 平均值=8
- 四分位间距=Q3-Q1=2 (即ΔQ)
- 最大值区间: Q3+1.5ΔQ = 12
- 最小值区间: Q1-1.5ΔQ = 4
- mild outlier = 3.5
- extreme outlier = 0.5
1 | sns.boxplot(x="day", y="total_bill", hue="time", data=tips) |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8bbd7240>
琴形图
1 | seaborn.violinplot(x=None, y=None, hue=None, data=None, order=None, hue_order=None, bw='scott', cut=2, scale='area', scale_hue=True, gridsize=100, width=0.8, inner='box', split=False, orient=None, linewidth=None, color=None, palette=None, saturation=0.75, ax=None, **kwargs) |
- split: bool, optional #琴形图是否从中间分开两部分
- scale: {“area”, “count”, “width”}, optional #用于调整琴形图的宽带。
- area——每个琴图拥有相同的面域;
- count——根据样本数量来调节宽度;
- width——每个琴图则拥有相同的宽度。
- inner: {“box”, “quartile”, “point”, “stick”, None}, optional #控制琴图内部数据点的形态。
- box——绘制微型 boxplot;
- quartiles——绘制四分位的分布;
- point/stick——绘制点或小竖条。
1 | sns.violinplot(x="total_bill", y="day", hue="time", data=tips) |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a9f97b8>
1 | sns.violinplot(x="day", y="total_bill", hue="sex", data=tips, split=True) #split: bool, optional #琴形图是否从中间分开两部分 |
条形图
显示值的集中趋势可以用条形图
1 | sns.barplot(x="sex", y="survived", hue="class", data=titanic) |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a5bc358>
点图
点图可以更好的描述变化差异
1 | sns.pointplot(x="sex", y="survived", hue="class", data=titanic) |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a5bcda0>
1 | #详细指定属性值 |
组合
1 | #琴型图 + 分散点图 |
<matplotlib.axes._subplots.AxesSubplot at 0x22d8a3f4908>
多层面板分类图
factorplot()
函数是对各种图形的一个更高级别的API封装,在Seaborn中非常常用。
1 | seaborn.factorplot(x=None, y=None, hue=None, data=None, row=None, col=None, col_wrap=None, estimator=<function mean>, ci=95, n_boot=1000, units=None, order=None, hue_order=None, row_order=None, col_order=None, kind='point', size=4, aspect=1, orient=None, color=None, palette=None, legend=True, legend_out=True, sharex=True, sharey=True, margin_titles=False, facet_kws=None, **kwargs) |
参数说明:
- x,y 数据集变量(变量名)
- hue 控制分组绘图(变量名)
- date 数据集 (数据集名)
- row,col 更多分类变量进行平铺显示 (变量名)
- col_wrap 每行的最高平铺数 (整数)
- estimator 在每个分类中进行矢量到标量的映射 (矢量)
- ci 置信区间 (浮点数或None)
- n_boot 计算置信区间时使用的引导迭代次数 (整数)
- units 采样单元的标识符,用于执行多级引导和重复测量设计 (数据变量或向量数据)
- order, hue_order 对应排序列表 (字符串列表)
- row_order, col_order 对应排序列表 (字符串列表)
- kind : 可选:point 默认, bar 柱形图, count 频次, box 箱体, violin 提琴, strip 散点,swarm 分散点
- size 每个面的高度(英寸) (标量)
- aspect 纵横比 (标量)
- orient 方向 (”v”/“h”)
- color 颜色 (matplotlib颜色)
- palette 调色板 (seaborn颜色色板或字典)
- legend hue的信息面板 (True/False)
- legend_out 是否扩展图形,并将信息框绘制在中心右边 (True/False)
- share{x,y} 共享轴线 (True/False)
- facet_kws FacetGrid的其他参数 (字典)
1 | sns.factorplot(x="day", y="total_bill", hue="smoker", data=tips) #默认是点图 |
<seaborn.axisgrid.FacetGrid at 0x22d8a79def0>
1 | sns.factorplot(x="day", y="total_bill", hue="smoker", data=tips, kind="bar") #绘制条形图 |
<seaborn.axisgrid.FacetGrid at 0x22d8a648748>
1 | sns.factorplot(x="day", y="total_bill", hue="smoker", |
<seaborn.axisgrid.FacetGrid at 0x22d8a867be0>
1 | sns.factorplot(x="time", y="total_bill", hue="smoker", |
<seaborn.axisgrid.FacetGrid at 0x22d8a8bcb00>
Seaborn热图绘制
1 | %matplotlib inline |
热图基础
1 | seaborn.heatmap(data, vmin=None, vmax=None, cmap=None, center=None, robust=False, annot=None, fmt='.2g', annotkws=None, linewidths=0, linecolor='white', cbar=True, cbarkws=None, cbar_ax=None, square=False, ax=None, xticklabels=True, yticklabels=True, mask=None, **kwargs) |
- data:矩阵数据集,可以使numpy的数组(array),如果是pandas的dataframe,则df的index/column信息会分别对应到heatmap的columns和rows
- linewidths,热力图矩阵之间的间隔大小
- vmax,vmin, 图例中最大值和最小值的显示值,没有该参数时默认不显示
- cmap:matplotlib的colormap名称或颜色对象;如果没有提供,默认为cubehelix map (数据集为连续数据集时) 或 RdBu_r (数据集为离散数据集时)
- center:将数据设置为图例中的均值数据,即图例中心的数据值;通过设置center值,可以调整生成的图像颜色的整体深浅;设置center数据时,如果有数据溢出,则手动设置的vmax、vmin会自动改变
- xticklabels: 如果是True,则绘制dataframe的列名。如果是False,则不绘制列名。如果是列表,则绘制列表中的内容作为xticklabels。 如果是整数n,则绘制列名,但每个n绘制一个label。 默认为True。
- yticklabels: 如果是True,则绘制dataframe的行名。如果是False,则不绘制行名。如果是列表,则绘制列表中的内容作为yticklabels。 如果是整数n,则绘制列名,但每个n绘制一个label。 默认为True。默认为True。
- annotate的缩写,annot默认为False,当annot为True时,在heatmap中每个方格写入数据
- annot_kws,当annot为True时,可设置各个参数,包括大小,颜色,加粗,斜体字等
- fmt,格式设置
1 | uniform_data = np.random.rand(3, 3) #生成数据 |
[[ 0.64272796 0.0229858 0.21897478]
[ 0.41076627 0.28860677 0.94805105]
[ 0.96513582 0.57781451 0.96400349]]
1 | # 改变颜色映射的值范围 |
1 | #为以0为中心的数据绘制一张热图 |
案例分析
1 | flights = sns.load_dataset("flights") #加载航班数据集 |
year | month | passengers | |
---|---|---|---|
0 | 1949 | January | 112 |
1 | 1949 | February | 118 |
2 | 1949 | March | 132 |
3 | 1949 | April | 129 |
4 | 1949 | May | 121 |
1 | flights = flights.pivot("month", "year", "passengers") #修改数据排列 |
year | 1949 | 1950 | 1951 | 1952 | 1953 | 1954 | 1955 | 1956 | 1957 | 1958 | 1959 | 1960 |
---|---|---|---|---|---|---|---|---|---|---|---|---|
month | ||||||||||||
January | 112 | 115 | 145 | 171 | 196 | 204 | 242 | 284 | 315 | 340 | 360 | 417 |
February | 118 | 126 | 150 | 180 | 196 | 188 | 233 | 277 | 301 | 318 | 342 | 391 |
March | 132 | 141 | 178 | 193 | 236 | 235 | 267 | 317 | 356 | 362 | 406 | 419 |
April | 129 | 135 | 163 | 181 | 235 | 227 | 269 | 313 | 348 | 348 | 396 | 461 |
May | 121 | 125 | 172 | 183 | 229 | 234 | 270 | 318 | 355 | 363 | 420 | 472 |
1 | ax = sns.heatmap(flights) #绘制热图 |
1 | ax = sns.heatmap(flights, annot=True,fmt="d") #在heatmap中每个方格写入数据,按照整数形式 |
1 | ax = sns.heatmap(flights, linewidths=.5) #热力图矩阵之间的间隔大小 |
1 | ax = sns.heatmap(flights, cmap="YlGnBu") #修改热图颜色 |
1 | ax = sns.heatmap(flights, cbar=False) #不显示热图图例 |