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

R中概率密度函数曲线超出边界时无法正确绘制的问题及修正需求

问题原因与解决方案

为什么曲线在边界处没有直接归零?

  1. 离散采样的衔接问题:curve或geom_function都是通过绘制离散采样点的连线生成曲线。默认采样点数量有限(比如geom_function默认n=101),在0-40范围内的采样点间隔为0.4。这导致x=9.6处(norm_pdf=0)和x=10处(norm_pdf非零)之间会画出一条斜线,而非理论上的垂直边界,视觉上就像曲线没有直接归零。
  2. 函数本身的边界取值:dunif(x,10,30)在x=10和x=30处返回1/20=0.05(符合连续均匀分布的密度定义),所以norm_pdf(10)和norm_pdf(30)本身是非零值,而边界外的点取值为0,采样点的连线放大了这种过渡效果。

如何实现符合定义的正确绘图?

方法1:手动构造带关键节点的绘图数据

直接生成包含边界点、边界外区间和区间内密集采样点的数据框,确保曲线在边界处垂直衔接:

library(ggplot2)

# 保留原函数定义
f <- function(z) 2*z^2 - 15*z + 15
fp <- function(x) f(x) * dunif(x, 10, 30) 
norm_const <- function(func, l=10, u=30) integrate(func, l, u)$value 
norm_pdf <- function(x) ifelse(x < 10 | x > 30, 0, fp(x) / norm_const(fp))

# 构造包含边界的采样点:左边界外、10、区间内、30、右边界外
x_vals <- c(seq(0, 9.99, length.out=20), 10, seq(10.01, 29.99, length.out=100), 30, seq(30.01, 40, length.out=20))
plot_data <- data.frame(x = x_vals, y = norm_pdf(x_vals))

# 绘图
ggplot(plot_data, aes(x, y)) +
  geom_line() +
  xlab("x") +
  ylab("Density") +
  theme_minimal() +
  scale_x_continuous(limits=c(0, 40), breaks=seq(0, 40, 2))

这种方式让曲线在x<10时保持0,x=10处直接跳转到对应密度值,彻底消除过渡斜线。

方法2:增强采样密度并强制包含边界

如果想用geom_function,可以提高采样点数量并确保边界点被包含,让过渡斜线几乎不可见:

library(ggplot2)

# 显式定义函数的边界行为
norm_pdf <- function(x) ifelse(x < 10 | x > 30, 0, fp(x) / norm_const(fp))

# 用501个采样点(间隔0.08),确保边界点在采样范围内
ggplot() +
  geom_function(fun = norm_pdf, n = 501, xlim = c(0, 40)) +
  xlab("x") +
  ylab("Density") +
  theme_minimal() +
  scale_x_continuous(limits=c(0, 40), breaks=seq(0, 40, 2)) +
  # 可选:添加虚线标注边界
  geom_vline(xintercept = c(10, 30), color = "red", linetype = "dashed")

更多的采样点会让边界处的过渡斜线变得极窄,视觉上接近垂直边界。

方法3:分段绘制(完全贴合理论定义)

直接绘制三段曲线:边界外的水平线、区间内的函数曲线、边界处的垂直线,完全符合概率密度函数的定义:

library(ggplot2)

# 计算边界处的密度值
pdf_at_10 <- norm_pdf(10)
pdf_at_30 <- norm_pdf(30)

ggplot() +
  # 左边界外:0到10,y=0
  geom_segment(aes(x=0, y=0, xend=10, yend=0)) +
  # 右边界外:30到40,y=0
  geom_segment(aes(x=30, y=0, xend=40, yend=0)) +
  # 区间内的密度曲线
  geom_function(fun = norm_pdf, xlim = c(10, 30)) +
  # 边界处的垂直线
  geom_segment(aes(x=10, y=0, xend=10, yend=pdf_at_10), color="red") +
  geom_segment(aes(x=30, y=0, xend=30, yend=pdf_at_30), color="red") +
  xlab("x") +
  ylab("Density") +
  theme_minimal() +
  scale_x_continuous(limits=c(0, 40), breaks=seq(0, 40, 2))

这种方式完美呈现了“边界外为0、边界处垂直衔接、边界内为函数曲线”的理论效果。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.21 00:41:00