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

如何在ggplot2中修改热力图标签文本的颜色

热力图中区分周末的可视化优化

问题背景

我在制作热力图时需要区分周末日期,目前的做法是将周末对应的值设为负数,通过颜色刻度让其呈现蓝色,但效果不理想。希望保留周末的正值,同时通过修改标签文本颜色或给热力图块添加边框等方式区分周末,已有布尔列weekend标记是否为周末,求更优的可视化方案。

原实现代码

hours <- c(16, 17, 0, 1, 2, 21, 22, 9, 19, 20)
days <- c(0, 0, 3, 3, 3, 6, 6, 11, 21, 21)
value <- c(3, 60, -18, -60, -23, 51, 48, 49, 47, 40)
weekend<- c(FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)

df <- data.frame(hours, days, value, weekend)

h<-1
w<-1

ggplot(df, aes(days, hours)) +
  geom_tile(aes(fill = value, width = w, height = h)) +
  geom_text(aes(label = value), size = 3) +
  scale_fill_continuous(limits=c(-60,60),breaks=seq(-60,60,20),low = "blue", high = "red") +
  xlab("Day") +
  ylab("Hour") +
  scale_x_continuous(
    breaks = seq(0, 41, by = 7),
    expand = c(0.05, 0.05)
  ) +
  scale_y_continuous(
    breaks = seq(0, 23, by = 3),
    expand = c(0.05, 0.05)
  ) +
  coord_cartesian(xlim=c(0,41),ylim=c(0,23))

优化方案

方案1:根据周末设置标签文本颜色

保留所有数值的原始正值,直接利用weekend布尔列控制文本颜色,周末用白色文本,非周末用黑色,同时调整填充色刻度范围为0-60,让颜色仅反映数值大小:

hours <- c(16, 17, 0, 1, 2, 21, 22, 9, 19, 20)
days <- c(0, 0, 3, 3, 3, 6, 6, 11, 21, 21)
value <- c(3, 60, 18, 60, 23, 51, 48, 49, 47, 40)
weekend<- c(FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)

df <- data.frame(hours, days, value, weekend)

h<-1
w<-1

ggplot(df, aes(days, hours)) +
    geom_tile(aes(fill = value, width = w, height = h)) +
    # 根据weekend列映射文本颜色
    geom_text(aes(label = value, colour = weekend), size = 4) +
    # 自定义文本颜色规则
    scale_colour_manual(values = c("black", "white")) +
    scale_fill_continuous(limits=c(0,60),breaks=seq(0,60,10),low = "white", high = "red") +
    xlab("Day") +
    ylab("Hour") +
    scale_x_continuous(
        breaks = seq(0, 41, by = 7),
        expand = c(0.05, 0.05)
    ) +
    scale_y_continuous(
       breaks = seq(0, 23, by = 3),
       expand = c(0.05, 0.05)
    ) +
    coord_cartesian(xlim=c(0,41),ylim=c(0,23))

方案2:给周末区块添加加粗边框

如果需要更直观的区分效果,可以给周末的热力块添加加粗边框,搭配文本颜色修改实现双重区分:

hours <- c(16, 17, 0, 1, 2, 21, 22, 9, 19, 20)
days <- c(0, 0, 3, 3, 3, 6, 6, 11, 21, 21)
value <- c(3, 60, 18, 60, 23, 51, 48, 49, 47, 40)
weekend<- c(FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE)

df <- data.frame(hours, days, value, weekend)

h<-1
w<-1

ggplot(df, aes(days, hours)) +
    # 根据weekend设置边框颜色和粗细
    geom_tile(aes(fill = value, width = w, height = h, colour = weekend, size = weekend)) +
    geom_text(aes(label = value, colour = weekend), size = 4) +
    # 自定义边框和文本颜色规则
    scale_colour_manual(values = c("black", "white")) +
    scale_size_manual(values = c(0.2, 1)) + # 非周末细边框,周末粗边框
    scale_fill_continuous(limits=c(0,60),breaks=seq(0,60,10),low = "white", high = "red") +
    xlab("Day") +
    ylab("Hour") +
    scale_x_continuous(
        breaks = seq(0, 41, by = 7),
        expand = c(0.05, 0.05)
    ) +
    scale_y_continuous(
       breaks = seq(0, 23, by = 3),
       expand = c(0.05, 0.05)
    ) +
    coord_cartesian(xlim=c(0,41),ylim=c(0,23)) +
    theme(legend.position = "none") # 隐藏weekend相关图例

方案说明

  • 方案1视觉干扰小,适合仅需轻度区分周末的场景;
  • 方案2通过边框+文本颜色的双重标记,识别度更高,适合需要突出周末区块的场景;
  • 两种方案均保留了数值的原始正值,避免了修改数值导致的可视化误导。

内容的提问来源于Stack Exchange,提问作者Stephen Clark

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 08:19:59