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

直方图柱形与函数曲线尺寸不匹配问题求助

问题:直方图柱形过高,与函数曲线尺寸不匹配

我用R语言编写了代码,生成函数f的曲线并叠加直方图,但直方图柱形过高,不确定是数据还是函数存在问题,希望让直方图与函数线条的尺寸相近。

原代码如下:

library(ggplot2)
dev.new()
set.seed(1684)
x = seq(15, 33, by = 0.9)
f <- function(x) {
  out <- ifelse(
    x < 15 | 33 < x,
    0,
    ifelse(
      15 <= x & x <= 24,
      (2*(x-15))/((33-15)*(24-15)),
      ifelse(
        24 < x & x <= 33,
        (2*(33-x))/((33-15)*(33-24)),
        NA_real_
      )))
  if (any((is.na(out) | is.nan(out)) & (!is.na(x) & !is.nan(x)))) {
    warning("f(x) undefined for some input values")
  }
  out
}

x_accept <- numeric(0)
while (length(x_accept) < 105) {
  x1 = runif(1, min = 15, max = 33)
  num = runif(1, min = 0, max = 1)
  if (num < (f(x1)/2/(33-15))) {
    x_accept = c(x_accept, x1)
  }
}

histo <- data.frame(x = x_accept)
dat <- data.frame(x = x, y = f(x), z = x_accept)
ggplot(dat) +
  geom_line(aes(x, y), color = "red") +
  geom_histogram(aes(z), alpha = .5, binwidth = 0.5)

当前绘图中,直方图柱形远高于红色函数曲线,两者尺度完全不匹配。


解决方案

问题根源

直方图默认展示的是每个区间的样本计数,而函数f是一个概率密度函数(PDF),两者量级差异极大,导致柱形过高。要让两者匹配,需要把直方图的y轴转换为密度值。

修改后的代码

只需要在geom_histogram的aes中添加y = ..density..,同时优化数据结构让代码更清晰:

library(ggplot2)
set.seed(1684)

# 定义密度函数f
f <- function(x) {
  out <- ifelse(
    x < 15 | 33 < x,
    0,
    ifelse(
      15 <= x & x <= 24,
      (2*(x-15))/((33-15)*(24-15)),
      ifelse(
        24 < x & x <= 33,
        (2*(33-x))/((33-15)*(33-24)),
        NA_real_
      )))
  if (any((is.na(out) | is.nan(out)) & (!is.na(x) & !is.nan(x)))) {
    warning("f(x) undefined for some input values")
  }
  out
}

# 生成样本数据
x_accept <- numeric(0)
while (length(x_accept) < 105) {
  x1 = runif(1, min = 15, max = 33)
  num = runif(1, min = 0, max = 1)
  if (num < (f(x1)/2/(33-15))) {
    x_accept = c(x_accept, x1)
  }
}

# 准备绘图数据
curve_dat <- data.frame(x = seq(15, 33, by = 0.9), y = f(seq(15, 33, by = 0.9)))
hist_dat <- data.frame(x = x_accept)

# 绘图:直方图用密度值,与函数曲线对齐
ggplot() +
  geom_line(data = curve_dat, aes(x, y), color = "red") +
  geom_histogram(data = hist_dat, aes(x, y = ..density..), alpha = .5, binwidth = 0.5, fill = "steelblue")

修改说明

  1. 将直方图的y轴设置为..density..,让直方图展示概率密度,和函数f的输出尺度一致。
  2. 拆分曲线和直方图的数据框,避免同一数据框混合不同类型数据,逻辑更清晰。
  3. 给直方图添加填充色,方便与红色曲线区分。

修改后,直方图柱形高度会和函数曲线尺寸匹配,能直观对比样本分布与理论密度函数的拟合情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.09 05:15:38