如何为ggplot中每个变量设置独立颜色刻度?
为每个Y轴变量设置独立颜色刻度的ggplot解决方案
你当前的代码生成的热图会让所有变量共享同一色阶,但不同变量(比如连续型的Age、多分类的Tumor_Stage、二分类的Smoking_Status)的数值范围和含义差异很大,需要给每个变量单独配置颜色刻度。可以借助ggnewscale包的new_scale_fill()和new_scale_color()函数实现这个需求,核心思路是分图层绘制每个变量,每个图层单独设置颜色映射。
步骤1:安装并加载必要包
首先确保安装了ggnewscale和tidyverse相关包:
install.packages(c("tidyverse", "ggnewscale")) library(tidyverse) library(ggnewscale)
步骤2:完整实现代码(手动分层版本)
这种方式适合变量较少的场景,可以精细控制每个变量的颜色方案:
# 构造原始数据集 Case <- c("Case 1", "Case 2", "Case 3", "Case 4", "Case 5") Age <- c(53, 46, 72, 68, 45) Tumor_Stage <- c(1, 2, 3, 1, 2) Tumor_Grade <- c(3, 1, 2, 2, 1) Smoking_Status <- c(0,1 ,1 ,0 ,1) CD3 <- c(0,1,0,0,1) df <- tibble(Case, Age, Tumor_Stage, Tumor_Grade, Smoking_Status, CD3) # 初始化画布,逐个添加变量图层 ggplot() + # 1. Age变量(连续型,渐变色) geom_tile(data = df %>% mutate(Variables = "Age"), aes(x = Case, y = Variables, fill = Age, color = Age)) + scale_fill_gradient(name = "Age", low = "#f7fbff", high = "#08306b") + scale_color_gradient(name = "Age", low = "#f7fbff", high = "#08306b") + # 重置填充和颜色刻度,为下一个变量准备 new_scale_fill() + new_scale_color() + # 2. Tumor_Stage变量(多分类,离散色) geom_tile(data = df %>% mutate(Variables = "Tumor_Stage"), aes(x = Case, y = Variables, fill = factor(Tumor_Stage), color = factor(Tumor_Stage))) + scale_fill_discrete(name = "Tumor Stage") + scale_color_discrete(name = "Tumor Stage") + # 重置刻度 new_scale_fill() + new_scale_color() + # 3. Tumor_Grade变量(多分类,自定义离散色) geom_tile(data = df %>% mutate(Variables = "Tumor_Grade"), aes(x = Case, y = Variables, fill = factor(Tumor_Grade), color = factor(Tumor_Grade))) + scale_fill_viridis_d(name = "Tumor Grade", option = "plasma") + scale_color_viridis_d(name = "Tumor Grade", option = "plasma") + # 重置刻度 new_scale_fill() + new_scale_color() + # 4. Smoking_Status变量(二分类,手动配色) geom_tile(data = df %>% mutate(Variables = "Smoking_Status"), aes(x = Case, y = Variables, fill = factor(Smoking_Status), color = factor(Smoking_Status))) + scale_fill_manual(name = "Smoking Status", values = c("0" = "#e6f5c9", "1" = "#386641"), labels = c("Non-smoker", "Smoker")) + scale_color_manual(name = "Smoking Status", values = c("0" = "#e6f5c9", "1" = "#386641"), labels = c("Non-smoker", "Smoker")) + # 重置刻度 new_scale_fill() + new_scale_color() + # 5. CD3变量(二分类,手动配色) geom_tile(data = df %>% mutate(Variables = "CD3"), aes(x = Case, y = Variables, fill = factor(CD3), color = factor(CD3))) + scale_fill_manual(name = "CD3 Expression", values = c("0" = "#fee0d2", "1" = "#de2d26"), labels = c("Negative", "Positive")) + scale_color_manual(name = "CD3 Expression", values = c("0" = "#fee0d2", "1" = "#de2d26"), labels = c("Negative", "Positive")) + # 调整主题和轴标签 labs(x = "Case", y = "Variables") + theme_minimal()
步骤3:优化版本(循环批量处理)
如果变量数量较多,用循环可以减少重复代码,提高可维护性:
# 定义变量配置列表:包含变量名、类型、颜色刻度 var_config <- list( list(name = "Age", type = "continuous", fill_scale = scale_fill_gradient(name = "Age", low = "#f7fbff", high = "#08306b"), color_scale = scale_color_gradient(name = "Age", low = "#f7fbff", high = "#08306b")), list(name = "Tumor_Stage", type = "categorical", fill_scale = scale_fill_discrete(name = "Tumor Stage"), color_scale = scale_color_discrete(name = "Tumor Stage")), list(name = "Tumor_Grade", type = "categorical", fill_scale = scale_fill_viridis_d(name = "Tumor Grade", option = "plasma"), color_scale = scale_color_viridis_d(name = "Tumor Grade", option = "plasma")), list(name = "Smoking_Status", type = "binary", fill_scale = scale_fill_manual(name = "Smoking Status", values = c("0"="#e6f5c9", "1"="#386641"), labels = c("Non-smoker", "Smoker")), color_scale = scale_color_manual(name = "Smoking Status", values = c("0"="#e6f5c9", "1"="#386641"), labels = c("Non-smoker", "Smoker"))), list(name = "CD3", type = "binary", fill_scale = scale_fill_manual(name = "CD3 Expression", values = c("0"="#fee0d2", "1"="#de2d26"), labels = c("Negative", "Positive")), color_scale = scale_color_manual(name = "CD3 Expression", values = c("0"="#fee0d2", "1"="#de2d26"), labels = c("Negative", "Positive"))) ) # 初始化画布 p <- ggplot() # 循环添加每个变量的图层和刻度 for (i in seq_along(var_config)) { var <- var_config[[i]] # 准备当前变量的数据:添加Y轴标签,分类变量转因子 data_layer <- df %>% mutate(Variables = var$name, value = .data[[var$name]]) %>% {if (var$type != "continuous") mutate(., value = factor(value)) else .} # 添加热图块 p <- p + geom_tile(data = data_layer, aes(x = Case, y = Variables, fill = value, color = value)) # 添加颜色刻度 p <- p + var$fill_scale + var$color_scale # 非最后一个变量时,重置刻度系统 if (i != length(var_config)) { p <- p + new_scale_fill() + new_scale_color() } } # 调整主题和标签 p <- p + labs(x = "Case", y = "Variables") + theme_minimal() # 输出图表 print(p)
核心逻辑说明
- 每个变量单独作为一个
geom_tile图层,通过mutate生成统一的Variables列来对应Y轴位置 - 连续变量用
scale_fill_gradient设置渐变色,分类/二分类变量用scale_fill_discrete或scale_fill_manual设置离散色 new_scale_fill()和new_scale_color()会重置当前的颜色映射系统,让后续图层的颜色配置完全独立于之前的变量- 可以根据变量的实际含义自定义颜色,比如二分类变量用对比色,连续变量用渐变色,提升图表的可读性
内容的提问来源于stack exchange,提问作者Alphonse Charbel
相关产品推荐
相关产品推荐

