跳到正文
百沐一下百沐一下
本节目录

科研配色与色盲友好方案

跟完这篇,您能给自己的图选对一套配色:知道数据该配顺序、发散还是定性配色,明白为什么别再用彩虹色,手里握有一份色盲也分得清的调色板,还能一句话调出 Nature、Lancet 这类期刊常见的风格——并会用代码自查「这套色红绿色盲看得清吗」。

配色不是审美问题,是准确传达数据的问题。选错一类配色,会让读者读出并不存在的分界、误判数值大小,甚至有近十分之一的男性读者根本分不清您用红绿标出的两组。好在这件事有成熟的规矩可循,照着做就能又好看又不误导人。

第一步:先看您的数据是哪一类

配色的第一决定,不是「喜欢什么颜色」,而是「数据是什么结构」。数据结构定了,配色的大类就定了,剩下的只是挑具体调色板。

数据结构特征常见例子该用哪类配色
单向连续由低到高,只有一个方向表达丰度、−log10(p)、密度、计数顺序(sequential)
双向连续有一个有意义的中点,向两边发散z-score、log2FC、相关系数、差值发散(diverging)
无序类别若干并列的组,彼此没有大小分组、细胞类型、亚型、通路名定性(qualitative)

记住这张表,后面全是它的展开。选之前先问自己一句:我这一列值,是「越大越……」,还是「有正有负」,还是「几个平等的类别」?

顺序、发散、定性:三类配色怎么用

顺序配色:单向的量

数据从低到高单调变化时用顺序配色——颜色由浅到深(或由暗到亮)跟着数值走。首选 viridis 系列,它感知均匀、色盲友好、灰度打印也不乱(下文详述为什么)。

library(ggplot2)

ggplot(df, aes(x, y, color = value)) +
  geom_point() +
  scale_color_viridis_c()          # 连续型顺序配色,感知均匀、色盲友好

ColorBrewer 里的单色渐变(如 BluesGreensPurples)也很稳,适合热图或填色地图这类需要「一种色调、深浅表大小」的场景。

发散配色:有中点、分两个方向

数据有一个天然中点(通常是 0),向两边各表示一个方向时用发散配色。典型是「蓝—白—红」:负值蓝、中点白、正值红。关键是把中性色钉在中点上,否则红蓝深浅就失去可比性。

# 以 0 为中点的蓝-白-红发散配色(如画 log2FC、z-score)
ggplot(df, aes(x, y, fill = log2FC)) +
  geom_tile() +
  scale_fill_gradient2(low = "#3B4CC0", mid = "white", high = "#B40426",
                       midpoint = 0)   # midpoint 一定要设在有意义的中点上

常用的发散调色板有 RdBu(红—蓝)、RdYlBu(红—黄—蓝)、BrBG(棕—绿)、PuOr(紫—橙)。热图里把 z-score 断点设成对称(如 ±2),配一条 RdBu 反转色带,是最通行的做法,细节见 热图聚类:注释条与配色全解

定性配色:并列的类别

给分组、细胞类型这类无序类别上色时,要的是彼此区分度高、没有暗示大小顺序的一组色。这里别用 viridis——顺序配色采样出来,相邻类别颜色太像。改用为分类设计的调色板,比如色盲友好的 Okabe-Ito,或 ColorBrewer 的 Set2Dark2

# Okabe-Ito:8 色定性配色,专为色觉障碍设计(base R ≥ 4.0 内置)
okabe <- palette.colors(palette = "Okabe-Ito")

ggplot(df, aes(x, y, color = group)) +
  geom_point() +
  scale_color_manual(values = unname(okabe))

一条经验:定性配色的类别数越少越好。超过 7~8 类,再好的调色板也开始难分,这时考虑合并次要类别、或干脆在图上直接标名字,而不是硬塞更多颜色。

为什么别用彩虹色

彩虹色(rainbow / jet,红橙黄绿青蓝紫那条)是很多默认设置的老配色,但在数据可视化里它有三个硬伤,学界早有共识建议弃用:

  1. 感知不均匀。 相同大小的数值差,在不同色段看起来变化幅度不一样——绿色区一大片几乎同色、黄绿交界却陡变。结果是读者会在颜色突变处读出并不存在的边界(假边界 / banding)。
  2. 亮度非单调。 黄色最亮、蓝色偏暗,颜色的明暗和数值大小对不上。图一旦灰度打印或被色盲读者看到,大小关系就彻底乱了。
  3. 对色盲不友好。 红绿段本就是最难区分的方向,彩虹色把关键信息全压在这段上。

替换方案很简单:单向数据换 viridis(或单色渐变),双向数据换发散配色。 两者在感知均匀、亮度单调、色盲友好上都远胜彩虹色。

# 把默认/彩虹配色换成 viridis,一行的事
p + scale_color_viridis_c()                      # 默认 viridis
p + scale_color_viridis_c(option = "cividis")    # cividis:专为色觉障碍优化的顺序配色

色盲友好:怎么选、怎么自查

先认识问题有多普遍

红绿色觉障碍是最常见的一种。常被引用的数字是约 8% 的男性、约 0.5% 的女性有某种红绿色觉障碍(主要基于北欧裔人群的统计)。换算一下:一个几十人的读者群里,几乎一定有人分不清您用纯红纯绿标出的两组。所以色盲友好不是加分项,是基本盘。

主要类型只需记两类:

类型俗称难分的方向说明
红色盲 / 绿色盲(protan / deutan)红绿色盲红 ↔ 绿最常见,设计时重点避开纯红纯绿对比
蓝黄色盲(tritan)蓝黄色盲蓝 ↔ 黄罕见得多

直接选这几套,基本不出错

不想深究的话,从下面挑就行——它们都被广泛当作色盲友好的默认:

用途调色板怎么拿
顺序(连续)viridis / cividisscale_color_viridis_c()
发散(双向)RdBu、BrBG、PuOrRColorBrewer::brewer.pal(11, "RdBu")
定性(分类)Okabe-Ito(最多 8 色)palette.colors(palette = "Okabe-Ito")
定性(3~8 色)Set2 / Dark2RColorBrewer::brewer.pal(8, "Dark2")

ColorBrewer 还能一次筛出所有色盲友好的调色板:

library(RColorBrewer)
display.brewer.all(colorblindFriendly = TRUE)   # 只显示色盲友好的那些

再加一层保险:别只靠颜色

最稳的做法是不把区分完全押在颜色上,给同一信息叠加第二种编码,色盲读者、黑白打印都不怕:

  • 散点、折线:不同组同时换形状shape)或线型linetype);
  • 少数关键类别:干脆直接在图上标文字,不劳读者查图例对色;
  • 显著性:除了颜色,再画阈值虚线或加 * 标记。

用代码自查这套色

选完别凭感觉,用 colorspace 模拟一下色盲眼里的样子,一眼看出会不会撞色:

library(colorspace)

cols <- palette.colors(palette = "Okabe-Ito")[2:8]  # 取一组分类色
deutan(cols)      # 模拟「绿色盲」下这组色变成什么
protan(cols)      # 模拟「红色盲」
# demoplot(cols, "bar")   # 直接画出来预览更直观

如果模拟后有两块颜色变得几乎一样,就换掉其中一个,或叠加形状 / 标签兜底。

期刊常见配色:一键套用

审稿人和读者对某些配色有肌肉记忆——一看就知道「这是 Nature 那套」。R 里的 ggsci 包把主流期刊的配色打包成了现成的 ggplot 图层,套一行即可,省得自己调十六进制。

library(ggsci)

p + scale_color_npg()       # Nature 风格
p + scale_color_lancet()    # Lancet 风格
# 填充图形(柱、箱、面积)把 color 换成 fill:
p + scale_fill_nejm()

常用的几套:

期刊 / 风格定性配色函数
Nature(NPG)scale_color_npg()
Science(AAAS)scale_color_aaas()
Lancetscale_color_lancet()
JAMAscale_color_jama()
NEJMscale_color_nejm()
临床肿瘤(JCO)scale_color_jco()

两点提醒:

  1. 期刊配色主要是「定性配色」,适合给分组、类别上色;它们不替代顺序 / 发散配色,热图该用发散还是得用发散。
  2. 好看 ≠ 色盲友好。 这些期刊调色板是为观感设计的,不保证对色盲友好。用于关键的两组对比前,最好还是用上一节的 deutan() 自查一遍;拿不准就退回 Okabe-Ito。

一份可以直接照抄的默认

懒得每次纠结的话,把下面这套当默认,绝大多数图都够用、也不会出错:

  1. 单向连续量scale_*_viridis_c()
  2. 双向连续量(含 0)scale_fill_gradient2(..., midpoint = 0),蓝—白—红;
  3. 分类 → Okabe-Ito 或 Set2;类别多就直接标签;
  4. 要期刊感ggsci 挑一套,再用 deutan() 自查;
  5. 永远别用 彩虹 / jet;永远别只靠颜色区分关键信息。

配色对了,图才谈得上「读得懂、经得起看」。它和轴、阈值、标注一样,是一张图能不能讲清楚事情的一部分。

在平台上跑一遍

不想记这些调色板名字、也不想写代码调色,在 百沐一下 上传数据后,用一句话说清诉求就行——比如「画分组箱线图,用色盲友好的定性配色」,或「热图用蓝白红发散配色、以 0 为中点」,或「换成 Lancet 风格配色」。智能绘图会替您选对配色大类、套好调色板并出图,您再对话式微调即可,交付时还附上可复现的 R 代码。用法见 智能绘图使用指南

相关