rggplot2plotmixture-model

Set Axis Limits of mixfitEM plot


I want to set limits to the x-axis of the plot of the output of the mixfit function of the mixR package. This output is of class mixfitEM.

Reproducable example: First I simulate a mixture of log normals.

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])

Then I try to fit two log normals into this data using mixfit() from mixR. In the first attempt I tried to use the plot() function from the base package; but plot ignores the xlim argument.

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

plot(mod4, title = 'Log-Normal Mixture (2 components)', xlim=c(0,200))

Then I tried to plot with ggplot, which, in theory should be possible according to the mixR manual. But ggplot does not understand the mixfitEM class.

ggplot(mod4)+
  + coord_cartesian(xlim = c(0, 200))

produces the following error:

> ggplot(data.frame(mod4))+
+   + coord_cartesian(xlim = c(0, 200))
Error in as.data.frame.default(x[[i]], optional = TRUE, stringsAsFactors = stringsAsFactors) : 
  cannot coerce class ‘"mixfitEM"’ to a data.frame
> ggplot(mod4)+
+   + coord_cartesian(xlim = c(0, 200))
Error in `fortify()`:
! `data` must be a data frame, or other object coercible by `fortify()`, not an S3 object with class mixfitEM.
Run `rlang::last_error()` to see where the error occurred.

Solution

  • When you call plot on the mixfitEM object, you are creating a ggplot. The reason for this is that plot is a generic function, so when package authors create a new class, they are free to use whatever method they want to draw the plot. In this case, if you examine the source code of mixR:::plot.mixfitEM you will see it actually uses ggplot to draw its output. This means you can use ggplot syntax to modify the output:

    plot(mod4, title = 'Log-Normal Mixture (2 components)') + xlim(c(0, 200))
    

    enter image description here