You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在ggplot热图中为不同分组设置独立颜色渐变?

为ggplot热图的每个分组设置独立颜色渐变

要实现每个分组使用不同的颜色渐变,我们可以借助ggnewscale包来突破ggplot默认只能有一组填充映射的限制。下面是修改后的完整代码,以及关键步骤的解释:

完整代码

## dummy data -----------------------------------------------------------------------------
data <- data.frame(
 group = sample(c("Direct Patient Care", "Indirect Patient Care", "Education", "Rounds", "Handoff", "Misce"), 30, replace = T),
 pct = rnorm(30, mean = 50, sd = 8)
)
## generate group id
data <- data %>% group_by(group) %>% mutate(id = row_number())
data$grpid <- with(data, ifelse(group == "Direct Patient Care", 1, ifelse(group == "Indirect Patient Care", 2, ifelse(group == "Education", 3, ifelse(group == "Rounds", 4, ifelse(group == "Handoff", 5,6 ))))))

## draw graph ------------------------------------------------------------------------------
library(ggplot2)
library(dplyr)
library(ggnewscale) # 先安装:install.packages("ggnewscale")

p <- ggplot() +
  # Direct Patient Care:橙色渐变
  geom_tile(data = filter(data, group == "Direct Patient Care"), 
            aes(x = id, y = group, fill = pct)) +
  scale_fill_gradient2(low = "white", mid = "orange", high = "darkorange", 
                       limits = c(0, 80), name = "Direct Care\nTime, %") +
  new_scale_fill() + # 重置填充比例尺,用于下一个分组
  
  # Indirect Patient Care:紫色渐变
  geom_tile(data = filter(data, group == "Indirect Patient Care"), 
            aes(x = id, y = group, fill = pct)) +
  scale_fill_gradient2(low = "white", mid = "plum", high = "purple", 
                       limits = c(0, 80), name = "Indirect Care\nTime, %") +
  new_scale_fill() +
  
  # Education:黄色渐变
  geom_tile(data = filter(data, group == "Education"), 
            aes(x = id, y = group, fill = pct)) +
  scale_fill_gradient2(low = "white", mid = "gold", high = "goldenrod", 
                       limits = c(0, 80), name = "Education\nTime, %") +
  new_scale_fill() +
  
  # Rounds:红色渐变(你的需求)
  geom_tile(data = filter(data, group == "Rounds"), 
            aes(x = id, y = group, fill = pct)) +
  scale_fill_gradient2(low = "white", mid = "pink", high = "red", 
                       limits = c(0, 80), name = "Rounds\nTime, %") +
  new_scale_fill() +
  
  # Handoff:绿色渐变(你的需求)
  geom_tile(data = filter(data, group == "Handoff"), 
            aes(x = id, y = group, fill = pct)) +
  scale_fill_gradient2(low = "white", mid = "lightgreen", high = "darkgreen", 
                       limits = c(0, 80), name = "Handoff\nTime, %") +
  new_scale_fill() +
  
  # Misce:蓝色渐变(你的需求)
  geom_tile(data = filter(data, group == "Misce"), 
            aes(x = id, y = group, fill = pct)) +
  scale_fill_gradient2(low = "white", mid = "lightblue", high = "darkblue", 
                       limits = c(0, 80), name = "Misce\nTime, %") +
  
  # 保留你原来的主题设置
  theme(panel.background = element_rect(fill = "white", colour = "grey50"), 
        aspect.ratio = 0.4) +
  theme(panel.grid.major = element_blank(), panel.grid.minor = element_blank()) +
  scale_x_continuous(name = " ", breaks = seq(1, 8, by = 1)) +
  scale_y_discrete(name = " ") +
  theme(axis.text.x = element_text(angle = 0, hjust = 1, vjust = 1), 
        plot.title = element_text(hjust = 0.5)) +
  ggtitle("Heatmap of time spent doing activities across 194 shifts")

print(p)

关键细节说明

  • ggnewscale核心作用:每次调用new_scale_fill(),ggplot会重置填充映射规则,让后续的geom_tile()可以使用完全独立的颜色渐变,不会和之前的分组冲突。
  • 按分组筛选数据:用filter(data, group == "XXX")精准定位每个分组的数据集,确保每个geom_tile()只绘制对应分组的热图块。
  • 统一数值标尺:所有渐变都设置了相同的limits = c(0, 80),这样不同分组的颜色深浅能对应相同的百分比数值,保证可视化的准确性和可比性。
  • 渐变自定义:你可以根据需求调整scale_fill_gradient2low(浅色调)、mid(中间色调)、high(深色调)参数;如果不需要中间色,改用scale_fill_gradient(仅需设置low和high)即可。

内容的提问来源于stack exchange,提问作者mandy

火山引擎 最新活动