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

如何用ggplot绘制带横竖分隔线的渐变色彩风险矩阵?

风险矩阵分隔线解决方案

问题说明

我正尝试使用ggplot绘制带有渐变色彩的风险矩阵,各颜色的边界由参考书籍定义,矩阵需严格遵循该标准。目前我已实现基于像素值的渐变配色方案,但无法添加所需的横向和纵向分隔线,希望设置如附图所示的分隔界限。请问是否可行?

用户现有代码

library(tidyverse)
library(scales)
library(dplyr)

colour_breaks <- c(0,4,7,10,15)
colours <- c("green","blue","yellow","orange","red")

db <- seq(from=5,to=1,by=-0.1)%*%t(seq(from=1,to=5,by=0.1))
db<- as.data.frame(db)

row.names(db) <- db[,1]
colnames(db) <- seq(from=1,to=5,by=0.1)

db$ID <- db[,1]
db <-  db[-nrow(db),] 

db_long <- db %>% 
  gather(key = "variable", value = "value", -ID) %>%
  mutate(ID = as.numeric(ID)) %>%
  mutate(variable = as.numeric(variable))
    
plt1 <-  ggplot(data=db_long, aes(x=as.numeric(variable), y=as.numeric(ID), fill=value)) +
  geom_raster() +
  coord_cartesian(clip = "off") +
  annotate('segment', x = 3.4, xend = 3.4, y = -Inf, yend = 1.4,
           size = 0.1,
           alpha = 0.4) +
  scale_x_continuous(expand = c(0, 0)) + 
  scale_y_continuous(expand = c(0, 0), breaks=c(0,1,2,3,4,5)) + 
  geom_hline(yintercept=1.4, alpha=0.4) +
  geom_hline(yintercept=2.4, alpha=0.4) +
  geom_hline(yintercept=3.5, alpha=0.4) +
  ylab("Condition") +
  xlab("Critic") +
  ggtitle("Risk Matrix") + 
  scale_fill_gradientn(
    limits  = range(db_long$value),
    colours = colours[c(1, seq_along(colours), length(colours))],
    values  = c(0, scales::rescale(colour_breaks, from = range(db_long$value)), 1),
  ) +
  theme_bw()

print(plt1)

解决方案

完全可行,只需通过geom_segment替代原有零散的分隔线绘制逻辑,就能精准匹配书籍要求的分段界限。修改后的代码如下:

library(tidyverse)
library(scales)

colour_breaks <- c(0,4,7,10,15)
colours <- c("green","blue","yellow","orange","red")

# 重构数据生成逻辑,避免原数据的冗余和异常
db <- seq(from=5,to=1.1,by=-0.1) %>% 
  outer(seq(from=1,to=5,by=0.1), FUN = "*") %>%
  as.data.frame()

colnames(db) <- seq(from=1,to=5,by=0.1)
db$ID <- seq(from=5,to=1.1,by=-0.1)

db_long <- db %>% 
  gather(key = "variable", value = "value", -ID) %>%
  mutate(across(c(variable, ID), as.numeric))

# 用数据框统一管理所有分隔线的坐标,方便调整和维护
segments_df <- tibble(
  # 横向分段线
  x_start = c(1, 1, 3.4),
  x_end = c(3.4, 5, 5),
  y_start = c(1.4, 2.4, 3.5),
  y_end = c(1.4, 2.4, 3.5),
  # 纵向分段线
  x_start = c(x_start, 3.4),
  x_end = c(x_end, 3.4),
  y_start = c(y_start, 1.4),
  y_end = c(y_end, 5)
)

plt1 <- ggplot(data=db_long, aes(x=variable, y=ID, fill=value)) +
  geom_raster() +
  coord_cartesian(clip = "off") +
  # 批量绘制所有自定义分隔线
  geom_segment(data=segments_df, 
               aes(x=x_start, xend=x_end, y=y_start, yend=y_end),
               size=0.1, alpha=0.4, inherit.aes=FALSE) +
  scale_x_continuous(expand = c(0, 0)) + 
  scale_y_continuous(expand = c(0, 0), breaks=0:5) + 
  labs(y="Condition", x="Critic", title="Risk Matrix") + 
  scale_fill_gradientn(
    limits = range(db_long$value),
    colours = colours[c(1, seq_along(colours), length(colours))],
    values = c(0, scales::rescale(colour_breaks, from = range(db_long$value)), 1)
  ) +
  theme_bw()

print(plt1)

关键修改说明

  1. 统一分隔线管理:用数据框定义所有分隔线的起点和终点,通过geom_segment批量绘制,替代原有的零散geom_hline和annotate,更易调整以匹配书籍标准。
  2. 优化数据生成:重构矩阵数据的生成逻辑,避免原代码中ID列的重复值问题,数据处理更简洁。
  3. 简化代码结构:用across批量转换数据类型,减少冗余代码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.07 18:40:56