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

在ggplot中为ONI多边形数据基于阈值分色及解决图层对齐问题

ONI区域3.4异常图的阈值分色解决方案

核心思路

别再堆叠多层geom_ribbon瞎试,先把数据按阈值拆成三部分:

  • 中间灰色区:-0.5 ≤ ONI ≤ 0.5的部分(填充0到该区间内的ONI值)
  • 上方红色区:ONI > 0.5的部分(填充0.5到实际ONI值)
  • 下方蓝色区:ONI < -0.5的部分(填充实际ONI值到-0.5)

通过预处理数据生成每个区间的准确上下限,再用geom_ribbon分别绘制,保证图层完全对齐。

代码示例

假设你的数据包含日期(x轴)和ONI值(y轴),按以下步骤处理:

1. 加载包并准备数据

library(ggplot2)
library(dplyr)

# 模拟ONI数据(替换成你自己的真实数据)
set.seed(123)
df <- tibble(
  date = seq.Date(as.Date("1950-01-01"), as.Date("2020-12-01"), by = "month"),
  oni = rnorm(length(date), 0, 0.8)
)

# 预处理数据,拆分三个区间的上下限
df <- df %>%
  mutate(
    # 中间灰色区的上限:把ONI截断在±0.5之间
    gray_ymax = pmax(pmin(oni, 0.5), -0.5),
    # 红色区:仅保留ONI>0.5的部分,否则设为NA(自动不绘制)
    red_ymin = 0.5,
    red_ymax = ifelse(oni > 0.5, oni, NA),
    # 蓝色区:仅保留ONI<-0.5的部分,否则设为NA
    blue_ymax = -0.5,
    blue_ymin = ifelse(oni < -0.5, oni, NA)
  )

2. 绘制图形

ggplot(df, aes(x = date)) +
  # 先画蓝色区(底层)
  geom_ribbon(aes(ymin = blue_ymin, ymax = blue_ymax), fill = "blue", alpha = 0.7) +
  # 再画红色区
  geom_ribbon(aes(ymin = red_ymin, ymax = red_ymax), fill = "red", alpha = 0.7) +
  # 最后画中间灰色区(顶层,覆盖重叠部分)
  geom_ribbon(aes(ymin = 0, ymax = gray_ymax), fill = "darkgray") +
  # 添加阈值虚线
  geom_hline(yintercept = c(0.5, -0.5), linetype = "dashed", color = "black") +
  # 自定义标签和主题
  labs(x = "日期", y = "ONI 3.4 异常值") +
  theme_minimal()

为什么之前对齐不好?

之前的问题是没有给每个图层匹配准确的x-y范围,要么是数据缺失未处理,要么是ymin/ymax的逻辑不对。现在通过预处理生成每个x对应的精准上下限,三个图层共享同一套x轴数据,自然不会错位。

额外优化

如果想要颜色更贴合阈值边缘,可以调整alpha值让颜色过渡更自然,或者把darkgray换成更柔和的灰色,避免和红蓝冲突。

内容的提问来源于stack exchange,提问作者M. Beausoleil

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 20:15:10