用 Python 来做数据可视化:Seaborn

在 R 语言的数据可视化工具中,ggplot2 的地位不可撼动,而在 Python 中也有与之对位的 Matplotlib( 最初由 John D. Hunter 撰写,神经生物学家,不幸因癌症于2012年去世,Matplotlib 继续由社区进行维护和更新,特别提一下以表敬意 )。平心而论,ggplot2 的图形效果整体上确实比 Matplotlib 好不知道要多少,特别是早期版本的 Matplotlib,线条看起非常粗糙,颜色搭配也很土味,不过 Matplotlib 流行也一定是有其优点的。除了因为 Python 的用户群体数量大,那就是它的自由度和易用性。看有评价说 ggplot2 似乎已经形成一套自己完整的语法体系,可以单独成一门“语言“,如果从另外一个角度来解读,那就是说其语法是还比较复杂的,入门有一定门槛。事实上在 Python 中也是个 ggplot2 包,用法跟 R 语言中基本一样,显而易见,这是从 R 中抄过来的( Matplotlib 也是借用了 Matlab 中的绘图概念,Python 本身就像是一颗洋葱,虽然强大,但是一层一层剥到最后,纯粹 Python 的核心也就所剩无几了)。

稍微有点扯远,回到正题,接下来要介绍的 Seaborn 就结合了 Matplotlib 和 ggplot2 的优点,其脱胎于 Matplotlib,兼具 Matplotlib 使用的灵活性和 ggplot2 图形的美观性,同时还对一些繁琐的地方做了简化。

先看几张示例图:

different_scatter_variables
errorband_lineplots
faceted_lineplot
horizontal_boxplot
large_distributions
multiple_joint_kde
structured_heatmap

事实上,虽然 ggplot2 发布时间比 Seaborn 早,但是 Seaborn 在 GitHub 仓库的 Start 数量反而要比 ggplot2多。

GitHub 截图,上面是 Seaborn, 下面是 ggplot2;Github Star 的数量只是一个参考,并不能作为判断两者优劣标准,只能说两个包各有千秋

另一方面,如果你之前一直在使用 Matplotlib,那 seaborn 对于你来说基本就没什么学习成本,Matplotlib 的绝大多数设置和方法都可以直接在 Seaborn 中使用,毕竟 Seaborn 是以 Matplotlib 作为基础开发的。


安装

两种方法:Bioconda 和 PIP,非常简单,都是一行命令解决的问题。参考官网( https://seaborn.pydata.org/installing.html )安装,如果有问题装不上的,可以使用 GitHub 上的源代码(https://github.com/mwaskom/seaborn)来安装。

1. Bioconda

conda install seaborn

2. PIP

pip install seaborn

当前稳定版本是 0.9.0,依赖以下几个基本包:
numpy (>= 1.9.3)
scipy (>= 0.14.0)
matplotlib (>= 1.4.3)
pandas (>= 0.15.2)

注:Seaborn 支持 Python2.7 或 Python3.5 +,如果使用 Bioconda 的话可以不用考虑这个问题,在虚拟环境里会自动调整版本,况且现在还在使用 Python2.7 的人应该不多了吧 ...

强烈推荐使用 Bioconda + Jupyterlab 组合进行数据分析和可视化!


开始做图

先来看一些实例,看完就已经基本掌握 Seaborn 可以进行数据可视化了。

注:官方文档建议大家还是去读一读,算是各种文档中写得比较清晰的,只要跟着 Tutorial ( https://seaborn.pydata.org/tutorial.html )做一遍基本就都能明白和掌握;API 列表( https://seaborn.pydata.org/api.html )也非常简洁明了,做图的时候方便查询对应图表的用法和参数。如果你下定了决心要通读文档,那么无需再往下阅读,毕竟我只是“二手贩子”。最多最多再看下文末的论文数据实例,可能是文档中唯一没有的内容。

一般教程都是做“加法”,由简入繁,一层一层往上贴图。因为 Seaborn 入门太简单,这么做没什么意思,我们反其道而行之,做“减法”,先画复杂的图,再一层一层给它“扒”下来 ⊙‿⊙

Seaborn 把绘图函数按其统计学概念分成了几类:

可视化图表分类
Relational plots 关系图
Categorical plots 分类图
Distribution plots 分布图
Regression plots 回归图
Matrix plots 矩阵图


1. Relational plots : 关系图

什么是关系图?其实就是 散点图折线图。在 Seaborn 中可以通过 scatterplot()lineplot() 两个函数分别绘制,也可以只用一个神奇的函数就将两者绘制出来,那就是:relplot()

relplot 就是 scatterplo 和 lineplot 的更高级封装

注:这几个函数名都非常好记,前两个就不用说了,relplot 就是 relational plot 缩写

下面采用文档中的实例来讲解一下,怎么用 relplot 绘制 散点图折线图
这部分的作图讲解将使用 Seaborn 自带的示例数据集:tips(用于散点图) 和 fmri(用于折线图)。开始作图前,先把需要用到的库和数据载入

# 载入 Seaborn 
import seaborn as sns

# 设置一下 Seaborn 图表中轴的样式,共有 darkgrid, whitegrid, dark, white, ticks 几个选项,可以参考
# https://seaborn.pydata.org/generated/seaborn.set.html#seaborn.set
sns.set(style="ticks")

# 载入示例数据 tips 和 fmri
fmritips = sns.load_dataset("tips")
fmri = sns.load_dataset("fmri")

# 打印示例数据看一下
print(tips)
print(fmri)



tips 数据集

fmri 数据集

可以看出 tips 总共有 244 行 x 7列 数据,fmri 总共有 1064行 x 5列 数据。

1.1 散点图

可以先不着急看代码和解释,把所有示例图先看一遍,找找变化规律再看文字不迟。每个图都比其上一个减少一个参数,通过参数减少和图形的变化很容易就能明白每个参数到底对应的是什么设置,非常直观。

# relplot 散点图 1
sns.relplot(data=tips, x="total_bill", y="tip", hue="time", palette=["g", "r"], size="smoker", sizes=(50, 150), col="day", row="time")
散点图 1 参数解释和参考
# relplot 散点图 2
sns.relplot(data=tips, x="total_bill", y="tip", hue="time", palette=["g", "r"], size="smoker", sizes=(50, 150), col="day")

散点图 2 参数解释和参考
# relplot 散点图 3
sns.relplot(data=tips, x="total_bill", y="tip", hue="time", palette=["g", "r"], size="smoker", sizes=(50, 150))

散点图 3 参数解释和参考
# relplot 散点图 4
sns.relplot(data=tips, x="total_bill", y="tip", hue="time", palette=["g", "r"], size="smoker")

散点图 4 参数解释和参考
# relplot 散点图 5
sns.relplot(data=tips, x="total_bill", y="tip", hue="time", palette=["g", "r"])

散点图 5 参数解释和参考
# relplot 散点图 6
sns.relplot(data=tips, x="total_bill", y="tip", hue="time")

散点图 6 参数解释和参考
# relplot 散点图 7
sns.relplot(data=tips, x="total_bill", y="tip")

散点图 7 参数解释和参考

剩下的三个参数不用说你也看得出来,不能再删了。如果使用 scatterplot()
来绘制以上这些图,基本上是大同小异,除了 'row' 和 'col' 这两个参数不能用之外,其他参数都是一样的用法。有些不常用的参数在上文中也并未使用,大家可以去查阅文档。


1.2 折线图

折线图也是使用非常频繁的一种数据可视化方式,非常简单明了:

这张图看起来有点魔性

在 Seaborn 中绘制 折线图散点图 的方式区别不大,只是改变几个参数而已。

先来看个简单图例,估计八成以上的应用也就只到这种程度:

折线图 - 例1:在 JupyterLab 中做的折线图

先看下各个参数的解释:

参 数 作 用
height relplot 通用的参数,设定整个图形的高度
aspect relplot 通用的参数,设定图形的宽度与高度的倍数,如上示例宽度是高度的 1.5 倍
kind replot 在不指定的情况下,默认是画 ‘散点图’,通过这个参数指定为 ‘折线图’
data 这个不用解释了

再来看看用的数据是怎么样的,这里的数据集变量名为 wide_df。是先通过 Numpy 生成随机数,再通过 Pandas 转换成 Dataframe 的“伪造数据”:

结合图例可以看出:

图 形 元 素
纵 轴 每一列的值
横 轴 第一列的索引 date
折 线 分别代表了 a、b、c、d 列
折线图 - 例 1 代码:
# 折线图 - 例 1:
import numpy as np
import pandas as pd
index = pd.date_range("1 1 2000", periods=100, freq="m", name="date")
data = np.random.randn(100, 4).cumsum(axis=0)
wide_df = pd.DataFrame(data, index, ["a", "b", "c", "d"])

import seaborn as sns
sns.set(style="ticks")
sns.relplot(height=6, aspect=1.5, kind="line", data=wide_df)

这个应该是最常用和简单的折线图了,下面来看一个复杂的例子:

折线图 - 例 2.1:学“神经”的各位可能会觉得有点眼熟

这个要先看下数据,再解释参数。使用的是 Seaborn 自带示例数据集 fmri,前面已经有提到过,不过这里稍微做了一些处理,在绘图时只使用了一部分数据:

按 'region' 这一列只取了 'frontal' 这一部分,没特别的意义,纯粹为了好画图
折线图 - 例 2.2:按 'stim' 和 'cue' 分成两条线
折线图 - 例 2 代码:
import seaborn as sns
fmri = sns.load_dataset("fmri")
sns.set(style="ticks")

# 折线图 - 例 2.1:
sns.relplot(
    x="timepoint",
    y="signal",
    data=fmri.query("region == 'frontal'"),
    kind="line",
    size="event",
    sizes=(1, 2),
    hue="event",
    units="subject",
    estimator=None,
    lw=1.5,
    height=8,
    aspect=1.5
)

# 折线图 - 例 2.2:
sns.relplot(
    x="timepoint",
    y="signal",
    data=fmri.query("region == 'frontal'"),
    kind="line",
    size="event",
    sizes=(1, 2),
    hue="event",
    lw=2,
    height=8,
    aspect=1.5
)


未 完 待 续 ...



参考资料

Seaborn 官网
https://seaborn.pydata.org/index.html
Github
https://github.com/mwaskom/seaborn
如何使用 ggplot2 ?
https://www.zhihu.com/question/24779017
维基百科:matplotlib
https://zh.wikipedia.org/wiki/Matplotlib



易微升公众号



最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,530评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,403评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,120评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,770评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,758评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,649评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,021评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,675评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,931评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,751评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,410评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,004评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,969评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,042评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,493评论 2 343