如何绘制单单元格可展示多分类的类热图?适配纵向分类数据
绘制含平局的分类类热图(纵向数据)
需求说明
我有纵向分类数据,需可视化为类热图,数据包含三个层级:研究参与者、访视场次、日历回忆日志。每个访视的分类由日历数据的主导类别确定(如30天中28天为A类则归为A类),若出现平局(多个类别占比相同),需在热图中直观体现。目标效果参考类似Excel生成的类热图:
示例数据
dat <- data.frame(person=factor(paste0("id#", 1:5), levels = rev(paste0("id#", 1:5))), matrix(sample(LETTERS[1:3], 15, T), ncol = 3)) dat <- dat %>% mutate(X2 = case_when(person=="id#3" ~ "A;B;C", TRUE ~ X2))
实现方案
使用tidyverse和ggplot2处理数据并绘图,核心思路是拆分平局的多分类项,在对应单元格内绘制等分颜色块:
library(tidyverse) # 数据整理:宽格式转长格式,拆分平局的多分类 dat_long <- dat %>% pivot_longer(cols = -person, names_to = "visit", values_to = "category") %>% mutate(category = str_split(category, ";")) %>% unnest(category) %>% group_by(person, visit) %>% mutate(n = n(), x_start = (row_number()-1)/n, x_end = row_number()/n) %>% ungroup() # 自定义分类颜色映射 category_colors <- c("A" = "#1f77b4", "B" = "#ff7f0e", "C" = "#2ca02c") # 绘制类热图 ggplot(dat_long, aes(x = visit)) + # 绘制每个分类对应的色块,平局项等分单元格宽度 geom_rect(aes(y = person, xmin = x_start + as.numeric(factor(visit)) - 1, xmax = x_end + as.numeric(factor(visit)) - 1, ymin = as.numeric(factor(person)) - 0.45, ymax = as.numeric(factor(person)) + 0.45, fill = category)) + scale_fill_manual(values = category_colors) + # 调整坐标轴刻度与标签 scale_x_continuous(breaks = 1:length(unique(dat_long$visit)), labels = unique(dat_long$visit)) + scale_y_discrete(limits = rev(levels(dat$person))) + # 设置标题与标签 labs(x = "访视场次", y = "研究参与者", fill = "分类") + # 优化主题样式 theme_minimal() + theme(panel.grid = element_blank(), axis.text = element_text(size = 12), axis.title = element_text(size = 14), legend.title = element_text(size = 12))
效果说明
- 单一分类的访视单元格显示为纯色块
- 平局的访视单元格会被拆分为多个等宽色块,每个色块对应一个平局分类,直观展示平局情况
- 整体布局与Excel示例图风格一致,清晰呈现参与者-访视的分类分布
内容的提问来源于stack exchange,提问作者Connor Miller
相关产品推荐
相关产品推荐

