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

在ggplot中如何填充两条正态曲线之间的指定区域

解决方案:适配所有参数组合的正态曲线右侧区域填充

要解决两条正态曲线右侧区域的填充问题,核心是先生成两条曲线的具体数值数据,再用geom_ribbon精准控制填充范围。以下是重构后的通用函数,可适配任意mu和sigma组合:

完整代码实现

library(ggplot2)

graf_normal <- function(mu1, sigma1, mu2, sigma2, x_cutoff = NULL) {
  # 生成覆盖两条曲线的x序列(扩展4倍标准差确保包含所有主要区域)
  x_min <- min(mu1 - 4*sigma1, mu2 - 4*sigma2)
  x_max <- max(mu1 + 4*sigma1, mu2 + 4*sigma2)
  x_seq <- seq(x_min, x_max, length.out = 1000)
  
  # 计算两条正态曲线的密度值
  y1 <- dnorm(x_seq, mu1, sigma1)
  y2 <- dnorm(x_seq, mu2, sigma2)
  
  # 自动区分左侧(mu更小)和右侧曲线,对应y下限/上限
  if (mu1 < mu2) {
    y_low <- y1
    y_high <- y2
  } else {
    y_low <- y2
    y_high <- y1
  }
  
  # 自动确定填充起始点:优先取两条曲线的最右交点,无交点则取较大的mu
  if (is.null(x_cutoff)) {
    diff_y <- y1 - y2
    cross_idx <- which(diff(sign(diff_y)) != 0)
    x_cutoff <- if (length(cross_idx) > 0) {
      x_seq[tail(cross_idx, 1)]
    } else {
      max(mu1, mu2)
    }
  }
  
  # 构造包含填充标记的数据框
  plot_df <- data.frame(
    x = x_seq,
    y_low = y_low,
    y_high = y_high,
    fill_flag = x_seq >= x_cutoff
  )
  
  # 绘图
  ggplot(plot_df, aes(x = x)) +
    # 绘制两条正态曲线
    stat_function(fun = dnorm, args = list(mean = mu1, sd = sigma1), color = "#0073C2FF") +
    stat_function(fun = dnorm, args = list(mean = mu2, sd = sigma2), color = "#EFC000FF") +
    # 仅填充右侧区域:用ifelse过滤非填充区间为NA
    geom_ribbon(
      aes(ymin = ifelse(fill_flag, y_low, NA), ymax = ifelse(fill_flag, y_high, NA)),
      alpha = 0.3, fill = "#868686FF"
    ) +
    labs(x = "X值", y = "密度") +
    theme_minimal()
}

关键改进点

  • 预生成数值数据:避免stat_function动态生成数据导致geom_ribbon无法匹配的问题,确保每个x点都有明确的两条曲线y值。
  • 自动适配曲线位置:根据mu大小自动区分左侧(y下限)和右侧(y上限)曲线,兼容mu1 > mu2的反向场景。
  • 智能填充起始点:自动计算两条曲线的最右交点作为填充起点;若曲线无交点(如标准差差异极大导致不相交),则以较大的mu作为起始点。
  • 手动控制填充范围:支持传入x_cutoff参数,自定义填充的起始x值(例如graf_normal(250,7,253,3, x_cutoff=255))。

测试示例

调用问题中的参数组合:

graf_normal(250,7,253,3)

该代码会自动计算两条曲线的右交点,填充交点右侧、两条曲线之间的区域,完全适配参数需求。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 10:46:20