library(tidyverse)
library(RColorBrewer)
library(ggsci)
library(paletteer)
library(viridis)
library(patchwork)
library(here) # 用于构建项目路径,确保图表保存到正确位置
set.seed(2026)
dir.create(here("outputs", "figures"), recursive = TRUE, showWarnings = FALSE) #
showtext::showtext_auto(enable = TRUE) # 启用showtext自动加载字体
# 创建示例数据
demo_df <- expand.grid(
group = LETTERS[1:4],
time = c("Week 0", "Week 4", "Week 8", "Week 12")
) |>
mutate(
mean = case_when(
group == "A" ~ c(10, 11, 11.5, 12)[match(
time,
c("Week 0", "Week 4", "Week 8", "Week 12")
)],
group == "B" ~ c(10, 12, 14, 15)[match(
time,
c("Week 0", "Week 4", "Week 8", "Week 12")
)],
group == "C" ~ c(10, 13, 16, 18)[match(
time,
c("Week 0", "Week 4", "Week 8", "Week 12")
)],
group == "D" ~ c(10, 10.5, 11, 11)[match(
time,
c("Week 0", "Week 4", "Week 8", "Week 12")
)]
) +
rnorm(16, 0, 0.3),
se = runif(16, 0.3, 0.8),
time = factor(time, levels = c("Week 0", "Week 4", "Week 8", "Week 12"))
)好的配色方案有3条重要规则:
- 色盲友好:确保配色方案对色盲用户友好,避免使用难以区分的颜色组合,如红绿配色。可以使用专门设计的色盲友好调色板,如
ColorBrewer中的Set1、Set2等,或者viridis系列。 - 黑白打印可读:确保配色方案在黑白打印时仍然清晰可读。可以使用不同的灰度级别来区分不同的组别,或者使用不同的线型和点型来增强区分度。不要只靠颜色区分。
- 有内在的逻辑:渐变色表示连续变量;分类色表示分组变量;深浅表示严重程度或风险等级。
Note配色设计提示词
theme_publication <- function(
base_size = 11,
base_family = "times new roman",
legend_pos = c(0.15, 0.85)
) {
theme_classic(base_size = base_size, base_family = base_family) +
theme_sub_legend(
title = element_text(size = base_size, face = "bold"),
text = element_text(size = base_size - 1),
background = element_rect(fill = "white", color = "grey80", linewidth = 0.3),
key.size = unit(0.4, "cm"),
position = legend_pos
) +
theme_sub_plot(
title = element_text(size = base_size + 1, face = "bold", hjust = 0.5),
margin = margin(10, 15, 10, 10),
background = element_rect(fill = "white", color = NA),
) +
theme_sub_axis(
title = element_text(size = base_size, face = "bold"),
text = element_text(size = base_size - 1, color = "black")
) +
theme_sub_panel(background = element_rect(fill = "white", color = NA)) +
theme(
# 文字
text = element_text(family = base_family, size = base_size),
)
}
Note查看内置的配色方案
# 查看RColorBrewer的调色板
display.brewer.all()
# 查看适合色盲的调色板
display.brewer.all(colorblindFriendly = TRUE)
# 查看某个具体调色板的颜色代码
brewer.pal(8, "Set1") # 8种颜色的Set1调色板[1] "#E41A1C" "#377EB8" "#4DAF4A" "#984EA3" "#FF7F00" "#FFFF33" "#A65628"
[8] "#F781BF"
# 使用paletter包查看更多调色板的可用配色方案
paletteer::paletteer_d("RColorBrewer::Set1") # ColorBrewer的Set1配色方案<colors>
#E41A1CFF #377EB8FF #4DAF4AFF #984EA3FF #FF7F00FF #FFFF33FF #A65628FF #F781BFFF #999999FF
1 核心配色方案
针对不同组别的比较,选择合适的配色方案非常重要。以下是一些常用的配色方案,这里以代码的形式给出,可以直接复制使用:
# 两组比较-双色
COLOR_TWO <- c("#2166ac", "#d73027") # 蓝红配色,适合强调两组之间的对比
COLOR_TWO_BW <- c("#000000", "#888888") # 黑灰配色,适合黑白打印或强调对比的同时保持简洁
# 三组比较-三色
COLOR_THREE <- c("#377EB8", "#FF7F00", "#4DAF4A") # 蓝橙绿
COLOR_THREE_BW <- c("#000000", "#666666", "#CCCCCC") # 黑灰白
# 四组比较-四色
COLOR_FOUR <- c("#2166ac", "#d73027", "#1a9850", "#f5a623") # 蓝红绿橙
COLOR_FOUR_BW <- c("#000000", "#555555", "#999999", "#dddddd") # 黑灰白浅灰
# 色盲友好
COLOR_BLIND_FRIENDLY <- c(
"#E69F00",
"#56B4E9",
"#009E73",
"#F0E442",
"#0072B2",
"#D55E00",
"#CC79A7",
"#000000"
) # 色盲友好配色,适合需要考虑色盲用户的情况
# 火山图配色-上调、下调、无显著变化
COLOR_VOLCANO <- c(
"Up" = "#d73027", # 上调-红色
"Down" = "#2166ac", # 下调-蓝色
"NS" = "#AAAAAA" # 无显著变化-灰色
)
# 热图渐变色
# 用法:scale_fill_gradient2(low=HEAT_LOW, mid=HEAT_MID, high=HEAT_HIGH, midpoint=0)
HEAT_LOW <- "#2166AC" # 蓝(低表达/负值)
HEAT_MID <- "white" # 白(中间值)
HEAT_HIGH <- "#D73027" # 红(高表达/正值)
cat("✅ 配色字典加载完成\n")✅ 配色字典加载完成
cat("使用示例:scale_color_manual(values=COLOR_TWO)\n")使用示例:scale_color_manual(values=COLOR_TWO)
2 双色配色方案示例
- 使用场景:适合两组之间的比较,例如处理组与对照组,或者两种不同的处理方法。
- 配色逻辑:选择对比明显的颜色,如蓝色和红色,能够突出两组之间的差异。这组配色来源于ColorBrewer的”RdBu”调色板,经过调整以适合科学图表的需求。
p1 <- demo_df |>
filter(group %in% c("A", "B")) |>
ggplot(aes(x = time, y = mean, color = group, group = group, linetype = group)) +
geom_line(linewidth = 0.9) +
geom_point(size = 3) +
geom_errorbar(
aes(ymin = mean - se, ymax = mean + se),
width = 0.2,
linewidth = 0.6
) +
scale_color_manual(
values = COLOR_TWO,
labels = c("A" = "Control", "B" = "Treatment")
) +
scale_linetype_manual(
values = c("solid", "dashed"),
labels = c("A" = "Control", "B" = "Treatment")
) +
theme_publication() +
labs(x = "Time Point", y = "Mean Value")
p1
3 三色配色方案示例
- 使用场景:适合三组之间的比较,例如三种不同的处理方法或者三个不同的时间点。
- 配色逻辑:选择对比明显且易于区分的颜色,ColorBrewer的
Set1前三个颜色,均匀色差,色盲友好。
p2 <- demo_df |>
filter(group %in% c("A", "B", "C")) |>
ggplot(aes(x = time, y = mean, fill = group, group = group)) +
geom_col(
position = position_dodge(width = 0.7),
width = 0.6,
color = "black",
linewidth = 0.3
) +
geom_errorbar(
aes(ymin = mean - se, ymax = mean + se),
position = position_dodge(width = 0.7), # 调整误差条位置以匹配柱状图
width = 0.2,
linewidth = 0.5
) +
scale_fill_manual(
values = COLOR_THREE,
labels = c("A" = "Stage I", "B" = "Stage II", "C" = "Stage III")
) +
theme_publication() +
labs(x = " ", y = "Mean Value")
p2
4 直接使用顶刊的配色方案
适用场景:任何多组比较,追求发表质感
来源:ggsci包的
scale_color_npg()——NPG是Nature Publishing Group,这就是Nature系列期刊的配色。其他配色方案还有:scale_color_npg()# Nature Publishing Groupscale_color_lancet()# The Lancetscale_color_nejm()# NEJMscale_color_jco()# Journal of Clinical Oncologyscale_color_aaas()# Science(AAAS)scale_color_jama()# JAMA
5 黑白打印
p3 <- demo_df |>
ggplot(aes(x = time, y = mean, fill = group)) +
geom_col(
position = position_dodge(width = 0.7),
width = 0.6,
color = "black",
linewidth = 0.4
) +
geom_errorbar(
aes(ymin = mean - se, ymax = mean + se),
position = position_dodge(width = 0.7),
width = 0.25,
lineend = 0.5
) +
scale_fill_manual(values = COLOR_FOUR_BW) +
theme_publication()
p3
6 渐变色
- 使用场景:适合连续变量的可视化,例如热图、散点图中的颜色映射。
-
viridis系列是目前最推荐的渐变配色:色差均匀,色盲友好,黑白打印也清晰。
heat_mat <- expand.grid(x = 1:15, y = 1:15) |>
mutate(value = sin(x / 3) * cos(y / 3) + rnorm(225, 0, 0.2))
p4a <- ggplot(heat_mat, aes(x = x, y = y, fill = value)) +
geom_tile() +
scale_fill_viridis_c(name = "Value")
p4b <- ggplot(heat_mat, aes(x = x, y = y, fill = value)) +
geom_tile() +
scale_fill_gradient2(
low = HEAT_LOW,
mid = HEAT_MID,
high = HEAT_HIGH,
midpoint = 0,
name = "Value"
)
p4b