Search code examples
rplotnormalizationgammgcv

Normalize z-axis values onto [0, 1] when using vis.gam for a mgcv GAM


I have just finished fitting a GAM using the mgcv package (I will call this model gam1.5). I have been playing around with the vis.gam function and I have a question I have not been able to solve.

I would like to normalize the fitted values of my model so when I use vis.gam, the z-axis has limits [0, 1].

My idea was to apply the normalization formula in the $fitted.values of my GAM model as follows:

gam1.5$fitted.values<-(gam1.5$fitted.values-min(gam1.5$fitted.values))/(max(gam1.5$fitted.values)-min(gam1.5$fitted.values))

However, when I run the vis.gam, it does not change the scale of the z-axis. I was wondering if I am applying the normalization formula to the incorrect object (a different one to $fitted.values) within the GAM object.


Solution

  • Yes. Because vis.gam is based on predict.gam and your change to $fitted.values has no effect!

    In fact, you can't achieve your goal with vis.gam. This function simply produces a plot and returns nothing for user to later reproduce the plot (unless vis.gam is called again). This means, we will need to work with predict.gam. Here are the basic steps.

    • Set up a 2D grid / mesh. You may want to use exclude.too.far to filter data far away from training data to avoid ridiculous spline / polynomial extrapolation (as vis.gam does);
    • Construct a new data frame newdat (from the above grid) and call oo <- predict.gam(gam1.5, newdat, type = "terms") to obtain term-wise prediction. This is a matrix. You need to retain only the column associated with the 2D smooth you want to plot. Let's say this column is stored into a vector z;
    • Augment z into a matrix by padding NA for those too far data.
    • Normalize z onto [0, 1].
    • Use image or contour to produce the plot yourself.

    Ideally we should take an example (maybe from ?vis.gam) and work through the above steps. However, you returned to me saying that you quickly sorted out the problem using predict.gam. Then I will not add examples for demonstration.