You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 18:57:33