让图形充满魅力是非常重要的。当我们探索一个数据集并且要进行可视化,那么,把图画得令人愉悦终究是不错的。可视化,是与听众交流大量信息时的核心方法,在这种情况下,让图形变得能瞬间抓住听众的注意非常有必要。
matplotlib
支持高度的自定义,但是我们很难弄清楚应该如何调整才能让图片更具吸引力。Seaborn
提供了一系列定制好的主题和一个更高级的接口,用于调整基于matplotlib
的图形的外观。
import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt
我们来定义一个简单的函数,用来绘制一系列偏移的正弦曲线。它会帮助我们了解有哪些样式参数是可以调整的。
def sinplot(flip=1):
x = np.linspace(0, 14, 100)
for i in range(1, 7):
plt.plot(x, np.sin(x + i * .5) * (7 - i) * flip)
我们先看一下matplotlib
默认的风格:
sinplot()
我们可以使用set()
函数来切换到seaborn
的默认风格。值得注意的是,在0.8
版本以前,当我们import seaborn
的时候,seaborn.set()
就已经被调用了,在之后的版本,我们则必须显示地调用它。
sns.set()
sinplot()
Seaborn
将matplotlib
参数分成独立的两组。第一组用于设置图形的设计风格,第二组用于调整各种各样的图形元素,这样我们的图形就能很容易地并入不同的背景。
调整这些参数的接口是两对函数。我们可以用axes_style()
或者set_style()
来控制设计风格;至于控制图形元素的大小缩放,则需要使用plotting_context()
和set_context()
函数。两种情况下,axes_*
函数都会返回一个参数字典,set_*
函数则会设置matplotlib
的默认参数。
一、Seaborn
设计风格
seaborn
中有5种预设主题:darkgrid
、whitegrid
、dark
、white
和ticks
。它们各自针对不同的应用和个人偏好。默认的主题是darkgrid
。网格可以对定量信息提供参考(对照),而浅灰色则避免网格线与我们绘制的线条冲突。whitegrid
主题与那些拥有很多数据元素的图很像,但是它与这种图契合得更好。
sns.set_style("whitegrid")
data = np.random.normal(size=(20, 6)) + np.arange(6) / 2
sns.boxplot(data=data);
很多情况下网格是没有必要存在的,尤其是在类似演讲的场合中,我们只想要通过图形展示某种模式的时候(这时数值参考并不重要)。
sns.set_style("dark")
sinplot()
sns.set_style("white")
sinplot()
有时我们可能想要给图形增加些额外的结构,比如增加刻度尺:
sns.set_style("ticks")
sinplot()
二、去除图形边线
在white
和ticks
主题中,我们并不需要上边和右边的边界。我们可以使用despine()
来干掉他们:
sinplot()
sns.despine()
在有些图中,我们需要调整边界与图形之间的距离,这一点我们也可以通过despine()
来实现。当刻度尺不会覆盖整个坐标轴的范围时,trim
参数会帮助我们限制边界的显示范围:
f, ax = plt.subplots()
sns.violinplot(data=data)
sns.despine(offset=10, trim=True);
我们也可以通过额外的参数来决定去除哪些边界:
sns.set_style("whitegrid")
sns.boxplot(data=data, palette="deep")
sns.despine(left=True);
三、临时修改设计风格
虽然我们可以很容易地改来改去,但有些情况下,我们使用with
语句搭配axes_style()
函数会更好。使用这种方法,我们可以在一张图的不同坐标轴中使用不同的设计:
f = plt.figure()
with sns.axes_style("darkgrid"):
ax = f.add_subplot(1, 2, 1)
sinplot()
ax = f.add_subplot(1, 2, 2)
sinplot(-1)
四、重载seaborn
的设计元素
如果我们想定制seaborn
的设计风格,我们还可以给axes_style()
或者set_style()
的rc
参数传递一个字典,这个字典由各种各样的设置项组成。需要注意的是,我们只能重载那些已经被定义好的选项。(不过更高级的set()
函数可以接受任何matplotlib
参数组成的字典)。
如果我们想看它们支持哪些选项,我们可以不加任何参数地调用它们,这样它们就会返回当前的配置:
sns.axes_style()
{'axes.facecolor': 'white',
'axes.edgecolor': '.8',
'axes.grid': True,
'axes.axisbelow': True,
'axes.labelcolor': '.15',
'figure.facecolor': 'white',
'grid.color': '.8',
'grid.linestyle': '-',
'text.color': '.15',
'xtick.color': '.15',
'ytick.color': '.15',
'xtick.direction': 'out',
'ytick.direction': 'out',
'lines.solid_capstyle': 'round',
'patch.edgecolor': 'w',
'image.cmap': 'rocket',
'font.family': ['sans-serif'],
'font.sans-serif': ['Arial',
'DejaVu Sans',
'Liberation Sans',
'Bitstream Vera Sans',
'sans-serif'],
'patch.force_edgecolor': True,
'xtick.bottom': False,
'xtick.top': False,
'ytick.left': False,
'ytick.right': False,
'axes.spines.left': True,
'axes.spines.bottom': True,
'axes.spines.right': True,
'axes.spines.top': True}
然后我们就可以进行修改和重载了:
sns.set_style("darkgrid", {"axes.facecolor": ".9"})
sinplot()
五、缩放图形元素
有一系列单独的参数可以用于控制图形元素的缩放,这样我们就可以使用同样的代码来使得我们的图片可以适应不同的应用场景(有时可能需要更大的图片,但有时却刚好相反)。
首先我们先重置所有的设置:
sns.set()
我们有四种预设的背景,按照相对大小来排序,分别是paper
、notebook
、talk
和poster
。上文的那些图片中使用的都是默认的notebook
风格。
sns.set_context("paper")
sinplot()
sns.set_context("talk")
sinplot()
sns.set_context("poster")
sinplot()
前边我们了解的那些关于设计风格的函数的知识,大多数也适用于背景函数。
我们可以使用set_context()
搭配一个背景风格的名称,也可以直接重载一个由设置选项构成的字典。
当修改了背景之后,我们也可以单独缩放字体元素(这个选项也可以通过顶级的APIset()
函数来实现)。
sns.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 2.5})
sinplot()
与设计风格相似,我们可以使用with
语句临时调整图形的缩放。
不管是设计风格还是背景风格(缩放),我们都可以使用set()
函数快速完成设置。这个函数还可以设置默认的调色板,不过接下来我们会更加详细地探讨关于调色板的知识。