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

ggplot绘制3个泊松混合分布密度图报错及无效问题求助

泊松混合分布密度图绘制问题解决

问题背景

需要用ggplot绘制3个泊松分布的混合密度图,并叠加各成分的密度曲线,但代码报错且图形无法正常显示,原代码及报错信息如下:

原代码

# Rstudio
# 定义三个泊松分布的参数及权重
weights<- c(0.2, 0.08, 0.72)
lambda <- c(2.5, 30.4, 14.3)

# 创建泊松混合分布的数据框
data <- tibble(x = 0:20, pdf_mixture = rowSums(sapply(1:3, function(i) weights[i] * dpois(0:20, lambda[i]))))

# 使用ggplot2创建图形
ggplot(data, aes(x = x, y = pdf_mixture, color = factor(1:3))) +
  geom_line(size = 1) +
  labs(title = "Funzione di Densità della Mistura di 3 Poisson",
       x = "Valori",
       y = "Densità") +
  scale_color_manual(values = c("red", "green", "purple"),
                     labels = c("Componente 1", "Componente 2", "Componente 3"))

报错信息(翻译后)

<error/rlang_error>
`geom_line()` 执行出错:
! 计算美学映射时出现问题。
ℹ 错误出现在第1层。
由 `check_aesthetics()` 引发的错误:
! 美学映射的长度必须为1,或与数据行数(21)一致
✖ 请修正以下映射: `colour`
---
调用栈:
     ▆
  1. ├─base (local) `<fn>`(x)
  2. └─ggplot2:::print.ggplot(x)
  3.   ├─ggplot2::ggplot_build(x)
  4.   └─ggplot2:::ggplot_build.ggplot(x)
  5.     └─ggplot2:::by_layer(...)
  6.       ├─rlang::try_fetch(...)
  7.       │ ├─base::tryCatch(...)
  8.       │ │ └─base (local) tryCatchList(expr, classes, parentenv, handlers)
  9.       │ │   └─base (local) tryCatchOne(expr, names, parentenv, handlers[[1L]])
 10.       │ │     └─base (local) doTryCatch(return(expr), name, parentenv, handler)
 11.       │ └─base::withCallingHandlers(...)
 12.       └─ggplot2 (local) f(l = layers[[i]], d = data[[i]])
 13.         └─l$compute_aesthetics(d, plot)
 14.           └─ggplot2 (local) compute_aesthetics(..., self = self)
 15.             └─ggplot2:::check_aesthetics(evaled, n)

错误原因

  1. 美学映射不匹配:color = factor(1:3)的长度是3,但数据框data有21行,ggplot要求美学映射的长度必须与数据行数一致或为1,导致报错。
  2. 数据结构不合理:原数据仅包含混合后的总密度,没有单独存储各成分的密度值,无法直接绘制各成分曲线。
  3. x轴范围过小:第二个泊松分布的lambda为30.4,其概率峰值在30附近,但原x范围仅到20,该成分的概率几乎为0,会导致曲线无法显示。

修正方案

步骤1:构建长格式数据框

生成包含x值、各成分密度、混合密度的长格式数据,方便ggplot分组绘制。

步骤2:调整x轴范围

将x范围扩展到0:40,覆盖所有成分的主要取值区间。

步骤3:分图层绘制曲线

先绘制各成分的曲线,再叠加混合分布的曲线(用粗线突出)。

修正后代码

library(tidyverse)

# 定义参数及权重
weights <- c(0.2, 0.08, 0.72)
lambda <- c(2.5, 30.4, 14.3)
component_names <- c("成分1", "成分2", "成分3")

# 生成x值范围(覆盖所有成分的峰值区域)
x_vals <- 0:40

# 计算各成分的加权密度,并整理成长格式数据
component_data <- map_dfr(1:3, function(i) {
  tibble(
    x = x_vals,
    density = weights[i] * dpois(x_vals, lambda[i]),
    type = component_names[i]
  )
})

# 计算混合分布的密度
mixture_data <- tibble(
  x = x_vals,
  density = rowSums(map_dfc(1:3, function(i) weights[i] * dpois(x_vals, lambda[i]))),
  type = "混合分布"
)

# 合并数据
plot_data <- bind_rows(component_data, mixture_data)

# 绘制图形
ggplot(plot_data, aes(x = x, y = density, color = type)) +
  geom_line(size = 1) +
  # 单独设置混合分布的线宽为粗线
  geom_line(data = mixture_data, aes(x = x, y = density), color = "black", size = 1.5) +
  labs(
    title = "3个泊松分布的混合密度图",
    x = "取值",
    y = "概率密度",
    color = "分布类型"
  ) +
  scale_color_manual(
    values = c("red", "green", "purple", "black"),
    labels = c(component_names, "混合分布")
  ) +
  theme_minimal()

效果说明

  • 各成分曲线分别以红、绿、紫色显示,混合分布以黑色粗线突出。
  • x轴范围调整后,lambda=30.4的成分曲线能正常显示其峰值。
  • 长格式数据结构符合ggplot的分组绘图要求,解决了美学映射不匹配的问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 11:30:12