控制图形美观#

绘制美观的图形很重要。当您自己制作图形以探索数据集时,拥有赏心悦目的图形会很不错。可视化在向受众传达定量见解中也至关重要,在这种情况下,更需要拥有能够吸引注意力并吸引观众的图形。

Matplotlib 具有高度可定制性,但可能很难知道要调整哪些设置才能获得美观的图形。Seaborn 附带了许多定制主题和一个高级接口,用于控制 matplotlib 图形的外观。

import numpy as np
import seaborn as sns
import matplotlib.pyplot as plt

让我们定义一个简单的函数来绘制一些偏移正弦波,这将有助于我们查看可以调整的不同样式参数。

def sinplot(n=10, flip=1):
    x = np.linspace(0, 14, 100)
    for i in range(1, n + 1):
        plt.plot(x, np.sin(x + i * .5) * (n + 2 - i) * flip)

这是使用 matplotlib 默认值绘制的图形。

sinplot()
../_images/aesthetics_7_0.png

要切换到 seaborn 默认值,只需调用 set_theme() 函数。

sns.set_theme()
sinplot()
../_images/aesthetics_9_0.png

(请注意,在 0.8 之前的 seaborn 版本中,set_theme() 是在导入时调用的。在更高版本中,必须显式调用它)。

Seaborn 将 matplotlib 参数分成两组独立的组。第一组设置图形的美观样式,第二组缩放图形的各种元素,以便可以轻松地将其合并到不同的上下文中。

用于操作这些参数的接口是两对函数。要控制样式,请使用 axes_style()set_style() 函数。要缩放图形,请使用 plotting_context()set_context() 函数。在这两种情况下,第一个函数返回参数字典,第二个函数设置 matplotlib 默认值。

Seaborn 图形样式#

有五个预设的 seaborn 主题:darkgridwhitegriddarkwhiteticks。它们各自适合不同的应用场景和个人喜好。默认主题是 darkgrid。如上所述,网格有助于图形用作定量信息的查找表,白色灰度有助于网格不会与代表数据的线条竞争。whitegrid 主题类似,但它更适合数据元素密集的图形。

sns.set_style("whitegrid")
data = np.random.normal(size=(20, 6)) + np.arange(6) / 2
sns.boxplot(data=data);
../_images/aesthetics_11_0.png

对于许多图形(尤其是在演示文稿等设置中,您主要想使用图形来提供数据中模式的印象),网格就不那么必要了。

sns.set_style("dark")
sinplot()
../_images/aesthetics_13_0.png
sns.set_style("white")
sinplot()
../_images/aesthetics_14_0.png

有时您可能想要为图形提供一些额外的结构,这时刻度就很方便了。

sns.set_style("ticks")
sinplot()
../_images/aesthetics_16_0.png

移除轴脊#

whiteticks 样式都可以从移除顶部和右侧的轴脊中受益,因为它们没有必要。Seaborn 函数 despine() 可以被调用来移除它们。

sinplot()
sns.despine()
../_images/aesthetics_18_0.png

有些图形从将脊线从数据中偏移中受益,这也可以在调用 despine() 时完成。当刻度没有覆盖轴的整个范围时,trim 参数将限制剩余脊线的范围。

f, ax = plt.subplots()
sns.violinplot(data=data)
sns.despine(offset=10, trim=True);
../_images/aesthetics_20_0.png

您也可以使用 despine() 的其他参数来控制移除哪些脊线。

sns.set_style("whitegrid")
sns.boxplot(data=data, palette="deep")
sns.despine(left=True)
../_images/aesthetics_22_0.png

临时设置图形样式#

虽然在不同样式之间切换很容易,但您也可以在 with 语句中使用 axes_style() 函数来临时设置图形参数。这也允许您制作具有不同样式轴的图形。

f = plt.figure(figsize=(6, 6))
gs = f.add_gridspec(2, 2)

with sns.axes_style("darkgrid"):
    ax = f.add_subplot(gs[0, 0])
    sinplot(6)

with sns.axes_style("white"):
    ax = f.add_subplot(gs[0, 1])
    sinplot(6)

with sns.axes_style("ticks"):
    ax = f.add_subplot(gs[1, 0])
    sinplot(6)

with sns.axes_style("whitegrid"):
    ax = f.add_subplot(gs[1, 1])
    sinplot(6)

f.tight_layout()
../_images/aesthetics_24_0.png

覆盖 seaborn 样式的元素#

如果您想自定义 seaborn 样式,可以将参数字典传递给 axes_style()set_style()rc 参数。请注意,您只能通过这种方式覆盖样式定义中包含的参数。(但是,更高层的 set_theme() 函数接受任何 matplotlib 参数的字典)。

如果您想查看包含了哪些参数,可以只在没有参数的情况下调用该函数,它将返回当前设置。

sns.axes_style()

然后您可以设置这些参数的不同版本。

sns.set_style("darkgrid", {"axes.facecolor": ".9"})
sinplot()
../_images/aesthetics_28_0.png

缩放图形元素#

一组单独的参数控制图形元素的比例,这应该可以让您使用相同的代码来制作适合在更大的或更小的图形中使用的图形。

首先,让我们通过调用 set_theme() 来重置默认参数。

sns.set_theme()

按相对大小排列的四个预设上下文分别是 papernotebooktalkposternotebook 样式是默认样式,在上面的图形中使用。

sns.set_context("paper")
sinplot()
../_images/aesthetics_32_0.png
sns.set_context("talk")
sinplot()
../_images/aesthetics_33_0.png
sns.set_context("poster")
sinplot()
../_images/aesthetics_34_0.png

您现在了解的大多数关于样式函数的信息都应该适用于上下文函数。

您可以使用这些名称之一调用 set_context() 来设置参数,并且可以通过提供参数值字典来覆盖参数。

您还可以独立缩放字体元素的大小,同时更改上下文。(此选项也可以通过顶层的 set() 函数获得)。

sns.set_context("notebook", font_scale=1.5, rc={"lines.linewidth": 2.5})
sinplot()
../_images/aesthetics_36_0.png

类似地,您也可以在 with 语句下临时控制图形的大小。

样式和上下文都可以使用 set() 函数快速配置。此函数还设置默认调色板,但这将在教程的 下一节 中详细介绍。