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

如何为上下三角颜色不同的geom_tile热图调整轴顺序并保留颜色

解决指定轴顺序后geom_tile上下三角颜色错位问题

你遇到的问题是:用ggnewscale实现了上下三角颜色不同的热图,但添加scale_x/y_discrete(limits = c("b","a","c"))指定轴顺序后,上下三角的颜色对应关系乱了——比如Var1=b、Var2=a的色块本该是绿色(Lower三角),结果变成了蓝色(Upper三角)。

问题根源

原来的ifelse(Var1 < Var2, "Lower", "Upper")是基于字符字典序判断的,比如字符"b"比"a"大,所以Var1=b、Var2=a会被归为Upper。但修改轴顺序后,坐标轴的位置顺序(b→a→c)和字符字典序(a→b→c)不一致,这就导致判断逻辑和实际的三角位置不匹配了。

解决方法

把Var1和Var2转换成有序因子,指定我们想要的轴顺序,然后基于因子的水平位置(整数索引)来判断上下三角,而不是字符本身的大小。

完整代码

library(ggnewscale)
library(ggplot2)
library(dplyr)

data <- data.frame(
  Var1 = c("b", "c", "a", "c", "a", "b"),
  Var2 = c("a", "a", "b", "b", "c", "c"),
  val = c(-2.1113581, 0.6189813, -0.4770620, 0.8119133, -0.4029937, 0.7977290)
)

# 关键修改:将Var1和Var2转为有序因子,指定轴顺序
plot_data = data %>%
  mutate(
    Var1 = factor(Var1, levels = c("b", "a", "c"), ordered = TRUE),
    Var2 = factor(Var2, levels = c("b", "a", "c"), ordered = TRUE),
    # 基于因子的整数索引判断三角:Var1的位置在Var2下方/右侧为Upper,反之为Lower
    triangle = ifelse(as.integer(Var1) > as.integer(Var2), "Upper", "Lower")
  ) %>%
  group_split(triangle)

ggplot() +
  # Upper三角(蓝色)
  geom_tile(data=plot_data[[which(sapply(plot_data, function(x) x$triangle[1] == "Upper"))]], 
            aes(x=Var1, y=Var2, fill=val)) +
  scale_fill_gradient(low = "lightblue", high = "blue", name = "Upper Values") +
  
  new_scale_fill() +
  # Lower三角(绿色)
  geom_tile(data=plot_data[[which(sapply(plot_data, function(x) x$triangle[1] == "Lower"))]], 
            aes(x=Var1, y=Var2, fill=val)) +
  scale_fill_gradient(low = "lightgreen", high = "darkgreen", name = "Lower Values") +
  # 指定轴顺序(这里其实可以省略,因为因子已经指定了levels,ggplot会自动用这个顺序)
  scale_x_discrete(limits = c("b", "a", "c")) +
  scale_y_discrete(limits = c("b", "a", "c"))

说明

  1. 转成有序因子后,as.integer(Var1)会返回该因子水平在指定顺序中的位置(比如"b"是1,"a"是2,"c"是3),这样比较的是它们在坐标轴上的位置关系,完全匹配我们想要的轴顺序。
  2. 绘图时用which(sapply(...))来准确选取Upper/Lower的数据集,避免group_split后顺序变化导致的错误(因为group_split的结果顺序不一定固定)。
  3. 其实指定因子levels后,scale_x/y_discrete(limits)可以省略,ggplot会自动使用因子的levels作为轴顺序,不过加上也不影响。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 17:35:17