ggplot热图x轴标签按化合物类别着色异常问题求助
问题与解决方案
问题描述
使用ggplot绘制热图时,希望根据化合物类别对x轴的化合物标签进行颜色编码,但用element_text(color = data$Class_col)设置后,仅能显示预设9种颜色中的4种,无法实现每个化合物按对应Class_col字段颜色显示的预期效果。
相关数据
dput(data) structure(list(Compound = structure(c(1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L), levels = c("3-7-11-trimethyl-1-dodecanol-1", "3-7-11-trimethyl-1-dodecanol-1-1", "3-7-11-trimethyl-1-dodecanol-1-2", "8-methylenecyclooctene-3-4-diol", "nonanol", "2-octenal", "undecenal", "1-3-di-iso-propylnaphthalene", "1-ethyl-3-methyl-benzene", "2-6-dimethoxy-4-2-propenyl-phenol", "mesitylene", "naphthalene", "orcinol", "didecyl-ether", "2-ethyl-hexanoic-acid", "tetradecanoic-acid", "2-6-10-trimethyl-dodecane", "2-6-10-trimethyl-tetradecane", "4-methyl-undecane", "dodecane", "2-3-pinandiol", "2-4-10-Thujadiene", "3-carene", "5-9-dimethyl-4-8-decadien-3-ol", "cuminaldehyde", "cymene-8-ol", "geranyl-isovalerat", "limonene", "myrthenol", "p-cymene", "p-cymenene", "terpinen-4-ol", "thymol", "trans-verbenol", "verbenone", "verbenone-1", "α-pinene", "α-pinene-oxide", "β-pinene", "10-11-himachala-3-12-4-diene", "caryophyllene-oxid", "cuparaene", "curcurmene", "epicubebol", "globuol", "isoaromadendrene-epoxide", "isolongifolan-8-ol", "longifolene", "longipinene", "murolan-3-9-11-diene-10-peroxy", "murolan-3-9-11-diene-10-peroxy-1", "octahydro-4-8-8-9-tetramethyl-1-4-methanoazulen-7-1H-one", "sativene", "shyobunone", "silphiperfol-5-ene-1", "silphiperfol-5-ene-1-1", "silphiperfol-5-ene-1-2", "α-calacorene", "α-muurolene", "β-copaene", "γ-muurolene", "1-8-dimethyl-8-9-epoxy-4-isopropyl-spiro-4-5-decan-7-one", "2-ethylhexyl-acrylate", "2-methyl-5-propan-2-ylidene-cyclohexane-1-4-diol", "4-cyanocyclohexene", "4-hydroxy-2-methoxycinnamaldehyde", "5-5-dimethyl-4-3-oxobutyl-spiro-2-5-octane", "5-6-6-trimethyl-5-3-oxobut-1-enyl-1-oxaspiro-2-5-octan-4-one", "5-ethenyldihydro-5-methyl-2-3H-furanone"), class = "factor"), treatment = structure(c(4L, 3L, 2L, 5L, 1L, 5L, 1L, 2L, 4L, 3L), levels = c("Control", "Burned", "Sterilized", "Brown rot", "White rot"), class = "factor"), Mean_Area = c(0, 0, 0, 0, 7.73621262619831e-05, 0, 0, 0.000410894352497955, 0.000143643273264461, 0.00144943581719015), Class = structure(c(1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), levels = c("alcohol", "aldehyde", "aromatic compound", "ether", "fatty acid", "hydrocarbon", "monoterpene", "sesquiterpene", "unknown"), class = "factor"), Scaled_Area = structure(c(-0.447213595499958, -0.447213595499958, -0.447213595499958, -0.447213595499958, 1.78885438199983, -0.657316583959348, -0.657316583959348, 0.0165637838218952, -0.421736851046765, 1.71980623514357), dim = c(10L, 1L)), Class_col = c(alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue", alcohol = "blue")), row.names = c(NA, -10L), class = c("tbl_df", "tbl", "data.frame"))
原生成热图代码
Class_col <- c("alcohol" = "blue","aldehyde" = "orange","aromatic compound" = "black", "ether" = "green","fatty acid" = "purple","hydrocarbon" = "red","monoterpene" = "pink", "sesquiterpene" = "brown","unknown" = "gray") data$Class_col <- Class_col[data$Class] x <- ggplot(data, aes(x = Compound, y = treatment, fill = Scaled_Area)) + geom_tile(color = "black") + scale_fill_gradient2(low = "white", high = "darkorange3", mid = "yellow2", na.value = "lightgray", midpoint = 0) + labs(x = "", y = "") + theme_minimal() + theme(axis.text.y = element_text(size = 10, colour = "black"), axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 10, colour = data$Class_col), legend.position = "none") + scale_y_discrete(position = "right") + coord_fixed(ratio = 2.5) x
问题原因
element_text()的colour参数要求传入的颜色向量长度与x轴标签数量完全匹配,但原代码中data$Class_col是按行重复的(每个化合物对应多个treatment行),导致颜色向量长度远大于x轴标签的实际数量,ggplot会自动截断或循环使用颜色,从而出现显示异常。
解决方案
先创建唯一的化合物-类别颜色映射表,确保每个x轴标签对应唯一的颜色值,再将该映射传递给axis.text.x:
修改后的代码
Class_col <- c("alcohol" = "blue","aldehyde" = "orange","aromatic compound" = "black", "ether" = "green","fatty acid" = "purple","hydrocarbon" = "red","monoterpene" = "pink", "sesquiterpene" = "brown","unknown" = "gray") data$Class_col <- Class_col[data$Class] # 创建化合物与颜色的唯一映射,按x轴化合物顺序排序 compound_color_map <- data %>% distinct(Compound, Class_col) %>% arrange(Compound) # 提取与x轴标签顺序一致的颜色向量 x_axis_colors <- compound_color_map$Class_col x <- ggplot(data, aes(x = Compound, y = treatment, fill = Scaled_Area)) + geom_tile(color = "black") + scale_fill_gradient2(low = "white", high = "darkorange3", mid = "yellow2", na.value = "lightgray", midpoint = 0) + labs(x = "", y = "") + theme_minimal() + theme(axis.text.y = element_text(size = 10, colour = "black"), axis.text.x = element_text(angle = 90, hjust = 1, vjust = 0.5, size = 10, colour = x_axis_colors), # 使用唯一映射的颜色向量 legend.position = "none") + scale_y_discrete(position = "right") + coord_fixed(ratio = 2.5) x
说明
通过distinct()提取每个化合物对应的唯一颜色,再按x轴化合物的顺序排序,确保颜色向量与x轴标签一一对应,这样就能实现每个化合物标签按其所属类别显示对应颜色的效果。
内容的提问来源于stack exchange,提问作者Claudio Sbaraglia
相关产品推荐
相关产品推荐

