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

如何设置mixR包mixfit输出的mixfitEM类对象绘图的x轴范围

问题

为R语言mixR包mixfit函数输出的mixfitEM类拟合结果设置x轴绘图范围时,遇到两个问题:

  • 调用base版plot()方法绘图时,传入的xlim参数被忽略不生效
  • 尝试用ggplot2绘图时,直接传入mixfitEM对象会报错,无法转换为ggplot支持的数据格式

可复现测试代码如下:

rm(list=ls())
library(mixR)
library(tidyverse)
set.seed(07062022)

N <- 1000
lbda=.5
mu1=1
Del=3
mu2=mu1+Del
components <- sample(1:2,prob=c((1-lbda), lbda),size=N,replace=TRUE)
mus <- c(mu1,mu2)
sds <- sqrt(c(1,.5))

Y <- rlnorm(n=N,meanlog=mus[components],sdlog=sds[components])

mod4 <- mixfit(Y, ncomp = 2, family = 'lnorm')

# base绘图尝试,xlim无效
plot(mod4, title = 'Log-Normal Mixture (2 components)', xlim=c(0,200))

# ggplot绘图尝试,报错
ggplot(mod4)+
  coord_cartesian(xlim = c(0, 200))

运行ggplot代码的报错信息:

Error in `fortify()`:
! `data` must be a data frame, or other object coercible by `fortify()`, not an S3 object with class mixfitEM.

解决方案

方法1:base绘图(最简方案)

plot.mixfitEM默认以原始数据的最小值、最大值作为密度曲线的计算边界,不会自动适配传入的xlim参数。函数本身提供了xmin、xmax参数用于控制密度曲线的计算范围,同时搭配xlim控制坐标轴显示范围即可生效:

plot(mod4, 
     title = 'Log-Normal Mixture (2 components)',
     xmin = 0,    # 密度曲线计算起点
     xmax = 200,  # 密度曲线计算终点
     xlim = c(0, 200) # x轴显示范围
)

如果需要调整x轴刻度,可以额外搭配axis()函数自定义刻度位置。

方法2:ggplot2自定义绘图(更高自由度)

mixR包没有为mixfitEM类提供ggplot2的fortify方法,因此不能直接将模型对象传入ggplot(),需要手动从模型结果中提取原始数据、拟合密度等元素,再组装图层,即可自由调整坐标轴、主题等所有样式:

# 1. 提取原始数据直方图密度
hist_obj <- hist(mod4$x, breaks = 50, plot = FALSE)
hist_df <- data.frame(
  x_mid = hist_obj$mids,
  density = hist_obj$density,
  width = diff(hist_obj$breaks)[1]
)

# 2. 计算指定x范围内的拟合密度
x_seq <- seq(0, 200, length.out = 1000)
# 整体混合密度
total_dens <- dmixlnorm(x_seq, mod4$mu, mod4$sd, mod4$pi)
# 各组分单独密度
comp_dens_list <- lapply(1:mod4$ncomp, function(i) {
  mod4$pi[i] * dlnorm(x_seq, meanlog = mod4$mu[i], sdlog = mod4$sd[i])
})
dens_df <- data.frame(
  x = rep(x_seq, times = mod4$ncomp + 1),
  density = c(total_dens, unlist(comp_dens_list)),
  type = rep(c("整体拟合", paste0("组分", 1:mod4$ncomp)), each = length(x_seq))
)

# 3. 绘图,自由设置x轴范围
ggplot() +
  geom_col(data = hist_df, aes(x = x_mid, y = density), 
           width = hist_df$width[1], fill = "grey85", color = "white") +
  geom_line(data = dens_df, aes(x = x, y = density, color = type, linewidth = type)) +
  scale_color_manual(values = c("整体拟合" = "black", "组分1" = "#E41A1C", "组分2" = "#377EB8")) +
  scale_linewidth_manual(values = c("整体拟合" = 1.2, "组分1" = 0.8, "组分2" = 0.8)) +
  coord_cartesian(xlim = c(0, 200)) + # 自定义x轴范围
  labs(title = "Log-Normal Mixture (2 components)",
       x = "观测值", y = "密度", color = "", linewidth = "") +
  theme_bw()

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:57:17