求助:如何用ggplot绘制3*4矩阵展示51名患者的独立分组单元格
问题描述
现有51名患者的数据,患者分属两套测试组(Limited test battery与Extensive test battery)的不同分组。需要绘制一个3*4的矩阵图,展示每位患者对应的两套测试组分组情况,以及两组分类是否一致。当前使用的R语言ggplot代码存在聚类重叠问题,无法为每个患者提供独立单元格:
long_data<-melt(data) x=long_data$Limited y=long_data$Extensive ggplot(data_long, aes(x = x, y = y,fill=Factor)) +geom_tile()+ geom_text(aes(label=number))+ labs(x='Limited test battery', y='Extensive test battery')
修改建议
1. 修正基础错误
首先统一变量名:代码中定义了long_data,但ggplot调用的是data_long,先将二者改为一致。另外,不建议直接用melt处理数据,保留宽格式原始数据(每一行对应一位患者,包含Limited分组、Extensive分组、患者编号number、分类一致性标识Factor)更适合当前绘图需求。
2. 解决tile重叠问题
当多个患者属于同一(Limited, Extensive)交叉组时,默认的geom_tile会重叠,可通过以下两种方式实现每个患者对应独立单元格:
方式一:位置抖动法
给geom_tile和geom_text添加位置抖动参数,让同组内的tile分散在对应分组格子范围内:
ggplot(original_data, aes(x = Limited, y = Extensive, fill = Factor)) + geom_tile(position = position_jitter(width = 0.3, height = 0.3), color = "white") + geom_text(aes(label = number), position = position_jitter(width = 0.3, height = 0.3)) + labs(x = 'Limited test battery', y = 'Extensive test battery')
调整width和height的数值可以控制抖动幅度,避免tile超出分组格子。
方式二:手动位置偏移法
先为同一交叉组内的患者生成索引,再基于索引调整tile的位置,让同组患者的tile整齐排列:
library(dplyr) # 为每个(Limited, Extensive)组内的患者添加序号 original_data <- original_data %>% group_by(Limited, Extensive) %>% mutate(group_idx = row_number()) %>% ungroup() # 基于序号调整x轴位置,让同组tile横向排列 ggplot(original_data, aes(x = as.numeric(Limited) + (group_idx - 1)*0.2 - (max(group_idx)-1)*0.1, y = Extensive, fill = Factor)) + geom_tile(width = 0.18, color = "white") + geom_text(aes(label = number)) + scale_x_continuous(breaks = 1:3, labels = levels(original_data$Limited)) + labs(x = 'Limited test battery', y = 'Extensive test battery')
这里假设Limited有3个分组(对应数值1-3),通过计算偏移量让同组tile居中排列,width参数控制tile宽度,避免重叠。如果需要纵向排列,可改为调整y轴的位置。
3. 视觉优化建议
- 添加
color = "white"到geom_tile,让每个tile的边界更清晰 - 根据患者数量调整tile的
width/height和偏移量,保证布局紧凑且不拥挤 - 将
Factor设置为“分类一致”/“分类不一致”,用对比强烈的填充色突出差异
内容的提问来源于stack exchange,提问作者Jannet Philip
相关产品推荐
相关产品推荐

