11

I need to create some gam plots in ggplot. I can do them with the general plot function, but am unsure how to do with ggplot. Here is my code and plots with the regular plot function. I'm using the College data set from the ISLR package.

train.2 <- sample(dim(College)[1],2*dim(College)[1]/3)
train.college <- College[train.2,]
test.college <- College[-train.2,]
gam.college <- gam(Outstate~Private+s(Room.Board)+s(Personal)+s(PhD)+s(perc.alumni)+s(Expend)+s(Grad.Rate), data=train.college)
par(mfrow=c(2,2))
plot(gam.college, se=TRUE,col="blue")
Julius Vainora
  • 47,421
  • 9
  • 90
  • 102
Marvin Bahr
  • 135
  • 1
  • 2
  • 11

1 Answers1

20

See update below old answer.

Old answer:

There is an implementation of GAM plotting using ggplot2 in voxel library. Here is how you would go about it:

library(ISLR)
library(mgcv)
library(voxel)
library(tidyverse)
library(gridExtra)
data(College)

set.seed(1)
train.2 <- sample(dim(College)[1],2*dim(College)[1]/3)
train.college <- College[train.2,]
test.college <- College[-train.2,]
gam.college <- gam(Outstate~Private+s(Room.Board)+s(Personal)+s(PhD)+s(perc.alumni)+s(Expend)+s(Grad.Rate), data=train.college)

vars <- c("Room.Board", "Personal", "PhD", "perc.alumni","Expend", "Grad.Rate")

map(vars, function(x){
  p <- plotGAM(gam.college, smooth.cov = x) #plot customization goes here
  g <- ggplotGrob(p)
}) %>%
  {grid.arrange(grobs = (.), ncol = 2, nrow = 3)}

after a bunch of errors: In plotGAM(gam.college, smooth.cov = x) : There are one or more factors in the model fit, please consider plotting by group since plot might be unprecise

enter image description here

To compare to the plot.gam:

par(mfrow=c(2,3))
plot(gam.college, se=TRUE,col="blue")

enter image description here

You might also want to plot the observed values:

map(vars, function(x){
  p <- plotGAM(gam.college, smooth.cov = x) +
    geom_point(data = train.college, aes_string(y = "Outstate", x = x ), alpha = 0.2) +
    geom_rug(data = train.college, aes_string(y = "Outstate", x = x ), alpha = 0.2)
  g <- ggplotGrob(p)
}) %>%
  {grid.arrange(grobs = (.), ncol = 3, nrow = 2)}

enter image description here

or per group (especially important if you used the by argument (interaction in gam).

map(vars, function(x){
  p <- plotGAM(gam.college, smooth.cov = x, groupCovs = "Private") +
    geom_point(data = train.college, aes_string(y = "Outstate", x = x, color= "Private"), alpha = 0.2) +
    geom_rug(data = train.college, aes_string(y = "Outstate", x = x, color= "Private"  ), alpha = 0.2) +
    scale_color_manual("Private", values = c("#868686FF", "#0073C2FF")) +
    theme(legend.position="none")
  g <- ggplotGrob(p)
}) %>%
  {grid.arrange(grobs = (.), ncol = 3, nrow = 2)}

enter image description here

Update, 08. Jan. 2020.

I currently think the package mgcViz offers superior functionality compared to the voxel::plotGAMfunction. An example using the above data set and models:

library(mgcViz)
viz <- getViz(gam.college)
print(plot(viz, allTerms = T), pages = 1)

enter image description here

plot customization is similar go ggplot2 syntax:

trt <- plot(viz, allTerms = T) +
  l_points() +
  l_fitLine(linetype = 1)  +
  l_ciLine(linetype = 3) +
  l_ciBar() +
  l_rug() +
  theme_grey() 

print(trt, pages = 1)

enter image description here

This vignette shows many more examples.

missuse
  • 19,056
  • 3
  • 25
  • 47
  • I'm getting this error after running that code. Error in plotGAM(gam.college, smooth.cov = x) : gamFit is not a object of type gam – Marvin Bahr Mar 25 '18 at 14:08
  • What library is the `gam` method you are using? If you could swap to `library(mgcv)` and `mgcv::gam` it would probably work. – missuse Mar 25 '18 at 14:11
  • @missuse, is it possible to plot two different models on the same plot, one for each level of 'Private', instead of using the interaction? – fibar Aug 03 '18 at 11:25
  • @fibar Yes. generate two models, then generate two plots and then combine in one plot using `gridExtra`, `cowplot` or any of the other few packages ment for this sort of thing. – missuse Aug 03 '18 at 11:38
  • 1
    @misuse I noticed that `plotGAM` and `plot` have different y axis. The y axis in `plotGAM` is predicted value of dependent variable. What does the y axis in `plot` mean? Their values are not the same (e.g., _8000~16000_ V.S. _-6000~6000_ ). – T X Apr 09 '19 at 06:06
  • @T X good catch. Here is an answer addressing this: https://stackoverflow.com/questions/15764810/changing-the-y-axis-of-default-plot-gam-graphs. When I get some time to research I will edit the answer. – missuse Apr 09 '19 at 08:57
  • Interestingly the gam model fitted now is different then the one fitted when the answer was posted using the same code. – missuse Apr 09 '19 at 09:03
  • great answer! love the series with the blue dots! – stats_noob Apr 25 '23 at 17:48