3. Seaborn基础:样式设置、绘图风格及默认调色板
Seaborn 这东西,说白了就是 Matplotlib 的「美颜滤镜」。我刚开始用 Matplotlib 画差异表达分析图时,经常花半小时调颜色、改网格、调坐标轴,结果还不好看。后来换 Seaborn,一行代码搞定样式。嗯,这节课就聊聊它的样式系统和调色板。
3.1 Seaborn 的「颜值」从哪来?
Seaborn 内置了一套完整的视觉规范。它把绘图元素拆成几个层次:主题风格决定底色和网格;上下文控制标签和线宽;调色板管理颜色映射。你想想看,这不就是给图表穿衣服吗?
我个人的习惯是,先用 sns.set_theme() 一把梭,再根据具体场景微调。但很多初学者不知道,这个方法其实是「一键重置」,会把所有样式都改掉。有一次我在项目里调了半天的字体大小,跑了一下 set_theme(),全没了……嗯,从那以后我记牢了:精细控制要用下面这些粒度更细的函数。
3.2 五种内置绘图风格
Seaborn 提供了 5 种开箱即用的主题。我用一个表格把它们说清楚:
| 风格 | 背景色 | 网格线 | 适用场景 |
|---|---|---|---|
darkgrid |
深灰 | 白色细线 | 科研论文、数据密集散点图 |
whitegrid |
白色 | 灰色细线 | 柱状图、箱线图、需要对照参考线的场景 |
dark |
深灰 | 无 | 演示大屏、深色背景 PPT |
white |
白色 | 无 | 出版插图、干净简约风格 |
ticks |
白色 | 仅坐标轴刻度线 | 折线图、配对比较图 |
使用方法很简单:
import seaborn as sns
import matplotlib.pyplot as plt
# 设置风格
sns.set_style("darkgrid")
# 画图
data = sns.load_dataset("iris")
sns.scatterplot(data=data, x="sepal_length", y="sepal_width", hue="species")
plt.show()
注意,set_style() 只影响当前图的风格,不会改调色板和字体大小。我个人最爱 whitegrid,尤其在差异表达的箱线图里,网格线能帮读者更快定位中位数和四分位距。
sns.axes_style() 查看当前风格的完整字典。想微调某个参数?把它返回的 dict 改一改,再传给 set_style() 就行。
3.3 上下文:控制图的「胖瘦高矮」
风格管「颜值」,上下文管「身材」。Seaborn 的 set_context() 可以一键调整标签字号、线条粗细、图例大小等尺寸参数。它内置四个级别:
- paper —— 适合期刊论文,字小、线细
- notebook —— 默认值,适合 Jupyter 交互探索
- talk —— 适合幻灯片,字大、线粗
- poster —— 适合海报,超级大字号
来看看实际效果:
sns.set_context("paper")
sns.scatterplot(data=data, x="sepal_length", y="sepal_width")
plt.show()
sns.set_context("poster")
sns.scatterplot(data=data, x="sepal_length", y="sepal_width")
plt.show()
你想想看,做差异表达分析时,基因名通常很长。如果用 paper 上下文,坐标轴标签可能会挤在一起。我一般先用 talk 或者自己调大 font_scale 参数。
# 放大字体 1.5 倍,其他尺寸等比缩放
sns.set_context("notebook", font_scale=1.5)
set_style() 和 set_context(),以为它俩是独立的。结果发现 set_context() 会重置部分样式参数(比如轴线颜色)。后来我改用 set_theme() 统一设置,或者先调 set_context() 再调 set_style(),才稳定下来。
3.4 默认调色板:颜色也有「性格」
调色板是 Seaborn 最让我省心的部分。它内置了多种颜色主题,适用于不同数据类型:
- 定性调色板 —— 离散类别,比如
deep、muted、bright、pastel、dark、colorblind - 顺序调色板 —— 连续数值,比如
Blues、Greens、Reds等 - 发散调色板 —— 有中间值的连续数据,比如
RdBu、coolwarm、vlag
默认情况下,Seaborn 使用 deep 调色板。这是 6 种高饱和度但又不刺眼的颜色。我个人觉得它在差异表达火山图里表现很好,上下调基因的颜色区分度够高。
# 查看当前调色板
sns.color_palette()
# 设置调色板
sns.set_palette("muted")
# 或者一次性设置主题 + 调色板
sns.set_theme(style="whitegrid", palette="muted")
如果你想知道某个调色板长什么样,用 sns.palplot() 直接可视化:
sns.palplot(sns.color_palette("Blues", 8))
plt.show()
RdBu 去画 5 个离散的基因簇,结果颜色过渡让人误以为中间有「中间状态」……误导性很强。
3.5 用 SVG 看 Seaborn 样式体系
下面这张图我画了 Seaborn 样式系统的整体结构。你跟着它走,基本不会迷路:
3.6 实战:快速搭建差异表达图的样式基底
讲完概念,咱们直接上手。假设你刚拿到一个差异表达数据框,里面有 log2FC 和 pvalue 两列。按我的习惯,先搭样式框架:
import seaborn as sns
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
# 1. 用 set_theme 统一初始化
sns.set_theme(
style="whitegrid",
context="talk",
palette="muted",
font="sans-serif",
font_scale=1.2
)
# 2. 模拟差异表达数据
np.random.seed(42)
n = 500
df = pd.DataFrame({
"log2FC": np.random.randn(n) * 2,
"pvalue": np.random.chisquare(2, n) / 10,
"gene": [f"Gene_{i}" for i in range(n)]
})
df["-log10(pvalue)"] = -np.log10(df["pvalue"] + 1e-10)
# 3. 画火山图(示意)
sns.scatterplot(data=df, x="log2FC", y="-log10(pvalue)", alpha=0.6)
plt.xlabel("log2 Fold Change")
plt.ylabel("-log10(pvalue)")
plt.title("Volcano Plot — DE Genes")
plt.show()
这段代码你复制到 Jupyter 里就能跑。注意 set_theme 里的 font_scale 参数——我习惯设到 1.2 到 1.5 之间,这样在幻灯片上不用眯眼看坐标轴标签。
whitegrid,建议把网格线色调调淡一点点。默认的灰色在某些显示器上有点抢眼。可以用 sns.set_style("whitegrid", {"grid.color": ".9"}) 把网格变成浅灰。
3.7 三个让我少加班的小经验
最后分享几个实际项目里攒下来的经验,希望对你有帮助:
- 配置文件统一管理样式 —— 我会把
set_theme的参数写在一个 YAML 文件里,不同项目(论文、PPT、海报)用不同的配置文件。这样改样式时不用翻代码。 - 调色板要照顾色盲读者 —— 差异表达分析里常用红绿表示上下调,但红绿色盲群体很常见。我现在改用
colorblind调色板或者RdBu,蓝橙对比对色盲更友好。 - 别频繁切换上下文 —— 同一个报告里,所有图的上下文最好统一。我见过有人前半段用
paper,后半段用talk,放在一起对比时字号忽大忽小,很掉档次。
sns.set_palette("Blues"),以为只改了颜色。结果它把调色板从原来的 6 种颜色缩减成单一色系的渐变。当我画一个包含 5 个分类的箱线图时,第 2 类和第 4 类的颜色几乎一样……后来我改用 sns.color_palette("Blues", 5) 显式指定颜色数量才解决。记住:set_palette 不带数量参数时,会用调色板的默认颜色数,顺序调色板默认只有 6 档。
好了,Seaborn 的样式系统就聊到这儿。你把它当成一个「主题包 + 尺寸控制器 + 颜色库」的组合拳就行。上手练两遍,你绘图效率至少能提一倍。