在这个 Seaborn 简介中,将学习如何使用 Python 最方便的库之一来进行数据可视化。
对于那些曾经使用过 Matplotlib 的人来说,你可能想知道,为什么需要10行代码才能制作出像样的直方图?
如果你正在寻找一个更简单的方式来绘制有吸引力的图表,那么你会爱上 Seaborn。
The Ultimate Python Seaborn Tutorial: Gotta Catch ‘Em All
介绍
Seaborn 为 Matplotlib 提供了一个高级接口,Matplotlib 是一个功能强大但有时很笨重的 Python 可视化库。
Seaborn 的官方网站表示:
如果 matplotlib “试图使简单的事情保持简单, 困难的事情成为可能”,seaborn 试图让一套明确定义的困难事情变得容易。
这是对 Seaborn 强项的不错总结。在实践中,“一套明确定义的困难事情”包括:
- 使用美观的默认主题。
- 设置自定义调色板。
- 制作有吸引力的统计图。
- 轻松灵活地显示分布。
- 可视化来自矩阵和
DataFrame
的信息。
最后三点就是为什么 Seaborn 是我们探索性分析的首选工具。这使得快速高效地“了解”数据非常容易。
然而,Seaborn 是 Matplotlib 的补充,而不是替代品。还有一些特殊设置仍然需要 Matplotlib。
开始
首先下载数据
import pandas as pd
from matplotlib import pyplot as plt
%matplotlib inline
import seaborn as sns
# Read dataset
df = pd.read_csv('data/Pokemon.csv', index_col=0)
df.head()
Name | Type 1 | Type 2 | Total | HP | Attack | Defense | Sp. Atk | Sp. Def | Speed | Stage | Legendary | |
---|---|---|---|---|---|---|---|---|---|---|---|---|
# | ||||||||||||
1 | Bulbasaur | Grass | Poison | 318 | 45 | 49 | 49 | 65 | 65 | 45 | 1 | False |
2 | Ivysaur | Grass | Poison | 405 | 60 | 62 | 63 | 80 | 80 | 60 | 2 | False |
3 | Venusaur | Grass | Poison | 525 | 80 | 82 | 83 | 100 | 100 | 80 | 3 | False |
4 | Charmander | Fire | NaN | 309 | 39 | 52 | 43 | 60 | 50 | 65 | 1 | False |
5 | Charmeleon | Fire | NaN | 405 | 58 | 64 | 58 | 80 | 65 | 80 | 2 | False |
Seaborn 的画图方法
Seaborn 最大的优势之一是其多样的绘图功能。例如,制作散点图只需要一句 lmplot()
即可.
有两种方法可以做到这一点:
- 第一种方法(推荐)是将你的
DataFrame
传递给data =
,同时将列名传递给轴参数,x =
和y =
。 - 第二种方法是直接将一系列数据传递给轴参数。
例如,我们来比较我们的”神奇宝贝”的攻击和防御统计:
# Recommended way
sns.lmplot(x='Attack', y='Defense', data=df)
# Alternative way
# sns.lmplot(x=df.Attack, y=df.Defense)
<seaborn.axisgrid.FacetGrid at 0x11044b4e0>
Seaborn 没有专门的散点图函数,这就是为什么你看到一条对角线。我们实际上使用了 Seaborn 拟合和绘制回归线的函数。
不过,每个绘图方法都有几个有用的选项。我们可以设置一下 lmplot()
:
- 首先,设置
fit_reg = False
来移除回归线,因为我们只需要一个散点图。 - 然后,设置
hue ='Stage'
根据神奇宝贝的进化阶段着色。这个hue
参数非常有用,因为它允许你使用颜色表示第三维信息。
# Scatterplot arguments
sns.lmplot(x='Attack', y='Defense', data=df,
fit_reg=False, # No regression line
hue='Stage') # Color by evolution stage
<seaborn.axisgrid.FacetGrid at 0x1105b6a58>
漂亮多了吧? 如果我们想改变坐标轴范围呢?
使用 Matplotlib 做自定义
记住,Seaborn 是 Matplotlib 的高级接口。Seaborn 将会为您提供大部分解决方法,但有时你也需要 Matplotlib 的帮助。
设置坐标轴范围就是其中一个例子:
- 首先,照常调用你的 Seaborn 绘图方法。
- 然后,调用 Matplotlib 的自定义函数。在这个例子中,我们将使用它
ylim()
和xlim()
。
# Plot using Seaborn
sns.lmplot(x='Attack', y='Defense', data=df,
fit_reg=False,
hue='Stage')
# Tweak using Matplotlib
plt.ylim(-10, None)
plt.xlim(-10, None)
(-10, 141.9881096001028)
Pandas 的作用
尽管这是 Seaborn 教程,但 Pandas 实际上扮演着非常重要的角色。如果能够合理使用 DataFrame
, Seaborn 会更加好用。
假设为神奇宝贝的战斗统计量绘制 box plot
# Boxplot
sns.boxplot(data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x1119424e0>
这是个说得过去的开始,但是我们可能希望删除一些列:
- 我们可以删除 Total,因为数据有单独统计。
- 我们可以移除 Stage 和 Legendary,因为它们不是战斗统计。
不过 Seaborn 来做这些可不容易。相反,DataFrame 做起来很简单。
让我们创建一个名为 stats_df
的新 DataFrame,它只保留统计信息列:
# Pre-format DataFrame
stats_df = df.drop(['Total', 'Stage', 'Legendary'], axis=1)
# New boxplot using stats_df
sns.boxplot(data=stats_df)
<matplotlib.axes._subplots.AxesSubplot at 0x111ab70b8>
Seaborn 主题风格
Seaborn 的另一个优点是它带来了优雅的风格主题。
接下来,制作 violin plot 并将主题更改为 “darkgrid”。
- violin plot 是 box plot 的良好替代品。
- 它能显示分布(通过小提琴的宽度),而不是仅汇总统计。
例如,我们可以看到神奇宝贝主要类型的攻击分布:
# Set theme
sns.set_style('darkgrid')
# Violin plot
sns.violinplot(x='Type 1', y='Attack', data=df)
<matplotlib.axes._subplots.AxesSubplot at 0x111dc2898>
正如你所看到的,Dragon 比 Ghost 更具攻击性,但它们也有更大的差异。
更多
Heatmap
查看矩阵数据
# Calculate correlations
corr = stats_df.corr()
# Heatmap
sns.heatmap(corr)
<matplotlib.axes._subplots.AxesSubplot at 0x111fd6f98>
Histogram
查看离散数据分布
# Distribution Plot (a.k.a. Histogram)
sns.distplot(df.Attack)
<matplotlib.axes._subplots.AxesSubplot at 0x19763277be0>
Bar Plot
查看范畴数据分布
# Count Plot (a.k.a. Bar Plot)
sns.countplot(x='Type 1', data=df, palette=pkmn_type_colors)
# Rotate x-labels
plt.xticks(rotation=-45)
(array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]),
<a list of 15 Text xticklabel objects>)
Factor Plot
根据种类分别绘图
# Factor Plot
g = sns.factorplot(x='Type 1',
y='Attack',
data=df,
hue='Stage', # Color by stage
col='Stage', # Separate by stage
kind='swarm') # Swarmplot
# Rotate x-axis labels
g.set_xticklabels(rotation=-45)
# Doesn't work because only rotates last plot
# plt.xticks(rotation=-45)
<seaborn.axisgrid.FacetGrid at 0x1976332a5c0>
Joint Distribution Plot
联合分布, 查看二维数据
# Joint Distribution Plot
sns.jointplot(x='Attack', y='Defense', data=df)
<seaborn.axisgrid.JointGrid at 0x197633df240>
现在你已经了解了 Seaborn 基础, 下一步可以边做边学了.