在探索中等维度数据时,经常需要在数据集的不同子集上绘制同一类型图的多个实例,这种技术有时被称为“网格”绘图,可以从复杂数据中快速提取大量信息。Matplotlib 为此提供了很好的支持,seaborn 构建于此之上,可直接将绘图结构和数据集结构关系起来。
要使用网格图功能,数据必须是 Pandas 数据框的形式,且为整洁形式,即用来绘图的数据框应该为每列一个变量,每一行一个观察的形式。
import numpy as np import matplotlib.pyplot as plt import seaborn as sns import warnings sns.set(style='whitegrid', color_codes=True) plt.rc( "figure", autolayout=True, figsize=(6, 5), titlesize=18, titleweight='bold', ) plt.rc( "axes", labelweight="bold", labelsize="large", titleweight="bold", titlesize=16, titlepad=10, ) %config InlineBackend.figure_format = 'retina' warnings.filterwarnings('ignore')
基于一定条件的多重小图
当我们想在数据集的不同子集中分别可视化变量分布或多个变量之间的关系时,就需要用到
首先,使用数据框初始化
tips = sns.load_dataset('tips', data_home='data', cache=True) tips.head()
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 |
g = sns.FacetGrid(tips, col='time') g.map(plt.hist, 'tip')
<seaborn.axisgrid.FacetGrid at 0x1351587d0>
g = sns.FacetGrid(tips, col='sex', hue='smoker') g.map(plt.scatter, 'total_bill', 'tip', alpha=0.7) g.add_legend()
<seaborn.axisgrid.FacetGrid at 0x135760fd0>
有几个传递给类构造函数的选项可以用于控制网格外观。
g = sns.FacetGrid(tips, row='smoker', col='time', margin_titles=True) g.map(sns.regplot, 'size', 'total_bill', color='.3', fit_reg=False, x_jitter=.1)
<seaborn.axisgrid.FacetGrid at 0x135776250>
通过提供每个面的高度以及纵横比来设置图形的大小
g = sns.FacetGrid(tips, col='day', height=4, aspect=0.5) g.map(sns.barplot, 'sex', 'total_bill')
<seaborn.axisgrid.FacetGrid at 0x1357ca2d0>
小图的默认排序是由 DataFrame 中的信息确定的。如果用于定义小图的变量是类别变量,则使用类别的顺序。否则,小图将按照各类的出现顺序排列。可以使用
ordered_days = tips.day.value_counts().index g = sns.FacetGrid(tips, row='day', row_order=ordered_days, height=1.7, aspect=4) g.map(sns.distplot, 'total_bill', hist=False, rug=True)
<seaborn.axisgrid.FacetGrid at 0x141b071d0>
可以用 seaborn 调色板(即可以传递给
pal = dict(Lunch='seagreen', Dinner='gray') g = sns.FacetGrid(tips, hue='time', palette=pal, height=5) g.map(plt.scatter, 'total_bill', 'tip', s=50, alpha=.7, linewidth=.5, edgecolor='white') g.add_legend()
<seaborn.axisgrid.FacetGrid at 0x1416bd5d0>
如果一个变量的类别太多,除了可以沿着列绘制之外,也可以“包装”它们以便跨越多行,执行此 wrap 操作时,不能使用
attend = sns.load_dataset('attention', cache=True, data_home='data').query("subject <= 12") g = sns.FacetGrid(attend, col='subject', col_wrap=4, height=2, ylim=(0, 10)) g.map(sns.pointplot, 'solutions', 'score', color='.3', ci=None)
<seaborn.axisgrid.FacetGrid at 0x142d5b210>
使用
with sns.axes_style('white'): g = sns.FacetGrid(tips, row='sex', col='smoker', margin_titles=True, height=2.5) g.map(plt.scatter, 'total_bill', 'tip', color='#334488', edgecolor='white', lw=.5) g.set_axis_labels('Total bill (US Dollars)', 'Tip') g.set(xticks=[10, 30, 50], yticks=[2, 6, 10]) g.fig.subplots_adjust(wspace=.02, hspace=.02)
对于需要更多自定义的情形,我们可以直接使用底层 matplotlib 的图形
g = sns.FacetGrid(tips, col='smoker', margin_titles=True, height=4) g.map(plt.scatter, 'total_bill', 'tip', color='#338844', edgecolor='white', s=50, lw=1) for ax in g.axes.flat: ax.plot((0,50), (0, .2*50), c='.2', ls='--') g.set(xlim=(0, 60), ylim=(0, 14))
<seaborn.axisgrid.FacetGrid at 0x146564790>
绘制成对数据关系
了解
iris = sns.load_dataset('iris', cache=True, data_home='data') g = sns.PairGrid(iris) g.map(plt.scatter)
<seaborn.axisgrid.PairGrid at 0x147f9ced0>
可以在对角线上绘制不同的函数,以显示每列中变量的单变量分布。但请注意,轴刻度与该绘图的计数或密度轴不对应。
一种常见的做法是通过单独的分类变量对观察结果进行着色。例如,iris 数据集三种不同种类的鸢尾花都有四个特征值,因此我们可以看到不同花在这些取值上的差异。
g = sns.PairGrid(iris, hue='species') g.map_diag(plt.hist) g.map_offdiag(plt.scatter) g.add_legend()
<seaborn.axisgrid.PairGrid at 0x1546152d0>
默认情况下,使用数据集中的每个数值列,但如果需要,我们可以专注于特定列。
g = sns.PairGrid(iris, vars=['sepal_length', 'sepal_width'], hue='species') g.map(plt.scatter)
<seaborn.axisgrid.PairGrid at 0x153daac10>
也可以在上三角和下三角中使用不同的函数来强调关系的不同方面。
g = sns.PairGrid(iris) g.map_upper(plt.scatter) g.map_lower(sns.kdeplot) g.map_diag(sns.kdeplot, lw=3, legend=False)
<seaborn.axisgrid.PairGrid at 0x1533b0a10>
对角线上具有单位关系的方形网格实际上只是一种特殊情况,我们也可以在行和列中使用不同的变量进行绘图。
g = sns.PairGrid(tips, y_vars=['tip'], x_vars=['total_bill', 'size'], height=4) g.map(sns.regplot, color='.3') g.set(ylim=(-1, 11), yticks=[0, 5, 10])
<seaborn.axisgrid.PairGrid at 0x164810d10>
我们可以使用不同的调色板,并将关键字参数传递到绘图函数中。
g = sns.PairGrid(tips, hue='size', palette='GnBu_d') g.map(plt.scatter, s=50, edgecolor='white') g.add_legend()
<seaborn.axisgrid.PairGrid at 0x164a364d0>
sns.pairplot(iris, hue='species', height=2.5)
<seaborn.axisgrid.PairGrid at 0x155e67fd0>
sns.pairplot(iris, hue='species', palette='Set2', diag_kind='kde', height=2.5)
<seaborn.axisgrid.PairGrid at 0x155f44410>