What is the ''reference value'' that is used by mgcv when plotting a smooth term? It is obvious for a parametric term, but not for a continuous variable used as a smooth term. Of course it doesn't matter when creating predictions; I'm just interested in how the plotting works.

For instance

library( mgcv )

set.seed( 1 )
SimData <- data.frame( x = runif( 100, 0, 1 ) )
SimData$y <- SimData$x^2 + rnorm( 100, 0, 0.1 )

fit <- gam( y ~ s( x ), data = SimData )
plot( fit )

results in

enter image description here

and I'd like to know how mgcv determined the scaling on the vertical axis, i.e. how is the place of zero is determined.


1 Answer 1


0 is the value of the model intercept in this case. More generally the value at 0 is the sum of contributions from all other terms so that the scale is the additive effect to the value of the linear predictor at that value of the covariate.


SimData <- data.frame(x = runif(100, 0, 1))
SimData <- transform(SimData, y = x^2 + rnorm(100, 0, 0.1))

fit <- gam(y ~ s(x), data = SimData)

newdata <- data.frame(x = seq(0, 1, length = 100))
pred <- predict(fit, newdata = newdata, type = "terms")

attr(pred, "constant")

Considering the above code example we have

> head(pred)
1 -0.3705257
2 -0.3676520
3 -0.3647786
4 -0.3619106
5 -0.3590587
6 -0.3562354
> attr(pred, "constant")

pred contains the contributions of $s(x)$ to the predicted values of the model at the given values of $x$. The predicted values of the model are the values in pred plus the model intercept

head(data.frame(fit1 = drop(pred + attr(pred, "constant")),
                fit2 = predict(fit, newdata)))

> head(data.frame(fit1 = drop(pred + attr(pred, "constant")),
+                 fit2 = predict(fit, newdata)))
         fit1        fit2
1 -0.03323248 -0.03323248
2 -0.03035874 -0.03035874
3 -0.02748538 -0.02748538
4 -0.02461740 -0.02461740
5 -0.02176549 -0.02176549
6 -0.01894214 -0.01894214

mgcv doesn't actually do that predict() call when plotting. It simply evaluates the values of the basis function at the values of $x$, and does a matrix multiplication of the resulting matrix with the vector of coefficients for the relevant basis functions.

bs <- PredictMat(fit$smooth[[1]], data = newdata)
head(data.frame(p1 = bs %*% coef(fit)[-1],
                p2 = drop(pred)))

The values in p1 here are the same as before (contributions to predicted values), but we've only worked with this covariate and not every other covariate in a potentially larger model. These are what are shown in the plot.

That 0 appears where it does is because of the sum to zero constraint imposed for identifiability reasons. Without this constraint (or a similar one, but others have undesirable properties) you could add a constant value to the model intercept and subtract the same value from the effect of the smooth and still end up with the same model. Hence there would be an infinite number of solutions to the model. The sum to zero constraint avoids this identifiability issue. And hence if the effect of the smooth has to sum to zero of the range of the covariate, 0 is at the overall mean of the response on the linear predictor scale.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.