Changelog
Source:NEWS.md
gratia (development version)
Bug fixes
partial_residuals()
was computing partial residuals from the deviance residuals. For compatibility withmgcv::plot.gam()
, partial residuals are now computed from the working residuals. Reported by @wStockhausen #273appraise()
was not passing theci_col
argument onqq_plot()
andworm_plot()
. Reported by Sate Ahmed.Couldn’t pass
mvn_method
on to posterior sampling functions from user facing functionsfitted_samples()
,posterior_samples()
,smooth_samples()
,derivative_samples()
, andrepsonse_derivatives()
. Reported by @stefgehrig #279
gratia 0.9.0
CRAN release: 20240327
Breaking changes

Many functions now return objects with different named variables. In order to avoid clashes with variable names used in user’s models or data, a period (
.
) is now being used as a prefix for generated variable names. The functions whose names have changed are:smooth_estimates()
,fitted_values()
,fitted_samples()
,posterior_samples()
,derivatives()
,partial_derivatives()
, andderivative_samples()
. In addition,add_confint()
also adds newlynamed variables.1. `est` is now `.estimate`, 2. `lower` and `upper` are now `.lower_ci` and `.upper_ci`, 3. `draw` and `row` and now `.draw` and `.row` respectively, 4. `fitted`, `se`, `crit` are now `.fitted`, `.se`, `.crit`, respectively 5. `smooth`, `by`, and `type` in `smooth_estimates()` are now `.smooth`, `.by`, `.type`, respectively.
derivatives()
andpartial_derivatives()
now work more likesmooth_estimates()
; in place of thevar
anddata
columns, gratia now stores the data variables at which the derivatives were evaluated as columns in the object with their actual variable names.
The way splineonthesphere (SOS) smooths (
bs = "sos"
) are plotted has changed to useggplot2::coord_sf()
instead of the previouslyusedggplot2::coord_map()
. This changed has been made as a result ofcoord_map()
being softdeprecated (“superseded”) for a few minor versions of ggplot2 by now already, and changes to the guides system in version 3.5.0 of ggplot2.The axes on plots created with
coord_map()
never really worked correctly and changing the angle of the tick labels never worked. Ascoord_map()
is superseded, it didn’t receive the updates to the guides system and a side effect of these changes, the code that plotted SOS smooths was producing a warning with the release of ggplot2 version 3.5.0.The projection settings used to draw SOS smooths was previously controlled via arguments
projection
andorientation
. These arguments do not affectggplot2::coord_sf()
, Instead the projection used is controlled through new argumentcrs
, which takes a PROJ string detailing the projection to use or an integer that refers to a known coordinate reference system (CRS). The default projection used is+proj=ortho +lat_0=20 +lon_0=XX
whereXX
is the mean of the longitude coordinates of the data points.
Defunct and deprecated functions and arguments
Defunct

evaluate_smooth()
was deprecated in gratia version 0.7.0. This function and all it’s methods have been removed from the package. Usesmooth_estimates()
instead.
Deprecated functions
The following functions were deprecated in version 0.9.0 of gratia. They will eventually be removed from the package as part of a clean up ahead of an eventual 1.0.0 release. These functions will become defunct by version 0.11.0 or 1.0.0, whichever is released soonest.
evaluate_parametric_term()
has been deprecated. Useparametric_effects()
instead.datagen()
has been deprecated. It never really did what it was originally designed to do, and has been replaced bydata_slice()
.
Deprecated arguments
To make functions in the package more consistent, the arguments select
, term
, and smooth
are all used for the same thing and hence the latter two have been deprecated in favour of select
. If a deprecated argument is used, a warning will be issued but the value assigned to the argument will be assigned to select
and the function will continue.
User visible changes

smooth_samples()
now uses a single call to the RNG to generate draws from the posterior of smooths. Previous to version 0.9.0,smooth_samples()
would do a separate call tomvnfast::rmvn()
for each smooth. As a result, the result of a call tosmooth_samples()
on a model with multiple smooths will now produce different results to those generated previously. To regain the old behaviour, addrng_per_smooth = TRUE
to thesmooth_samples()
call.Note, however, that using persmooth RNG calls with
method = "mh"
will be very inefficient as, with that method, posterior draws for all coefficients in the model are sampled at once. So, only userng_per_smooth = TRUE
withmethod = "gaussian"
. 
The output of
smooth_estimates()
and itsdraw()
method have changed for tensor product smooths that involve one or more 2D marginal smooths. Now, if no covariate values are supplied via thedata
argument,smooth_estimates()
identifies if one of the marginals is a 2d surface and allows the covariates involved in that surface to vary fastest, ahead of terms in other marginals. This change has been made as it provides a better default when nothing is provided todata
.This also affects
draw.gam()
. fitted_values()
now has some level of support for location, scale, shape families. Supported families aremgcv::gaulss()
,mgcv::gammals()
,mgcv::gumbls()
,mgcv::gevlss()
,mgcv::shash()
,mgcv::twlss()
, andmgcv::ziplss()
.gratia now requires dplyr versions >= 1.1.0 and tidyselect >= 1.2.0.
A new vignette Posterior Simulation is available, which describes how to do posterior simulation from fitted GAMs using {gratia}.
New features
Soap film smooths using basis
bs = "so"
are now handled bydraw()
,smooth_estimates()
etc. #8response_derivatives()
is a new function for computing derivatives of the response with respect to a (continuous) focal variable. First or second order derivatives can be computed using forward, backward, or central finite differences. The uncertainty in the estimated derivative is determined using posterior sampling viafitted_samples()
, and hence can be derived from a Gaussian approximation to the posterior or using a Metropolis Hastings sampler (see below.)derivative_samples()
is the work horse function behindresponse_derivatives()
, which computes and returns posterior draws of the derivatives of any additive combination of model terms. Requested by @jonathanmellor #237data_sim()
can now simulate response data from gamma, Tweedie and ordered categorical distributions.data_sim()
gains two new example models"gwf2"
, simulating data only from Gu & Wabha’s f2 function, and"lwf6"
, example function 6 from Luo & Wabha (1997 JASA 92(437), 107116).data_sim()
can also simulate data for use with GAMs fitted usingfamily = gfam()
for grouped families where different types of data in the response are handled. #266 and part of #265fitted_samples()
andsmooth_samples()
can now use the Metropolis Hastings sampler frommgcv::gam.mh()
, instead of a Gaussian approximation, to sample from the posterior distribution of the model or specific smooths respectively.posterior_samples()
is a new function in the family offitted_samples()
andsmooth_samples()
.posterior_samples()
returns draws from the posterior distribution of the response, combining the uncertainty in the estimated expected value of the response and the dispersion of the response distribution. The difference betweenposterior_samples()
andpredicted_samples()
is that the latter only includes variation due to drawing samples from the conditional distribution of the response (the uncertainty in the expected values is ignored), while the former includes both sources of uncertainty.fitted_samples()
can new use a matrix of usersupplied posterior draws. Related to #120add_fitted_samples()
,add_predicted_samples()
,add_posterior_samples()
, andadd_smooth_samples()
are new utility functions that add the respective draws from the posterior distribution to an existing data object for the covariate values in that object:obj > add_posterior_draws(model)
. #50basis_size()
is a new function to extract the basis dimension (number of basis functions) for smooths. Methods are available for objects that inherit from classes"gam"
,"gamm"
, and"mgcv.smooth"
(for individual smooths).data_slice()
gains a method for data frames and tibbles.typical_values()
gains a method for data frames and tibbles.fitted_values()
now works with models fitted using themgcv::ocat()
family. The predicted probability for each category is returned, alongside a Wald interval created using the standard error (SE) of the estimated probability. The SE and estimated probabilities are transformed to the logit (linear predictor) scale, a Wald credible interval is formed, which is then backtransformed to the response (probability) scale.fitted_values()
now works for GAMMs fitted usingmgcv::gamm()
. Fitted (predicted) values only use the GAM part of the model, and thus exclude the random effects.link()
andinv_link()
work for models fitted using thecnorm()
family.A worm plot can now be drawn in place of the QQ plot with
appraise()
via new argumentuse_worm = TRUE
. #62smooths()
now works for models fitted withmgcv::gamm()
.overview()
now returns the basis dimension for each smooth and gains an argumentstars
which ifTRUE
add significance stars to the output plus a legend is printed in the tibble footer. Part of wish of @noamross #214New
add_constant()
andtransform_fun()
methods forsmooth_samples()
.evenly()
gains argumentslower
andupper
to modify the lower and / or upper bound of the interval over which evenly spaced values will be generated.add_sizer()
is a new function to add information on whether the derivative of a smooth is significantly changing (where the credible interval excludes 0). Currently, methods forderivatives()
andsmooth_estimates()
objects are implemented. Part of request of @asanders11 #117draw.derivatives()
gains argumentsadd_change
andchange_type
to allow derivatives of smooths to be plotted with indicators where the credible interval on the derivative excludes 0. Options allow for periods of decrease or increase to be differentiated viachange_type = "sizer"
instead of the defaultchange_type = "change"
, which emphasises either type of change in the same way. Part of wish of @asanders11 #117
draw.gam()
can now group factor by smooths for a given factor into a single panel, rather than plotting the smooths for each level in separate panels. This is achieved via new argumentgrouped_by
. Requested by @RPanczak #89draw.smooth_estimates()
can now also group factor by smooths for a given factor into a single panel. The underlying plotting code used by
draw_smooth_estimates()
for most univariate smooths can now add change indicators to the plots of smooths if those change indicators are added to the object created bysmooth_estimates()
usingadd_sizer()
. See the example in?draw.smooth_estimates
.
smooth_estimates()
can, when evaluating a 3D or 4D tensor product smooth, identify if one or more 2D smooths is a marginal of the tensor product. If users do not provide covariate values at which to evaluate the smooths,smooth_estimates()
will focus on the 2D marginal smooth (or the first if more than one is involved in the tensor product), instead of following the ordering of the terms in the definition of the tensor product. #191For example, in
te(z, x, y, bs = c(cr, ds), d = c(1, 2))
, the second marginal smooth is a 2D Duchon spline of covariatesx
andy
. Previously,smooth_estimates()
would have generatedn
values each forz
andx
andn_3d
values fory
, and then evaluated the tensor product at all combinations of those generated values. This would ignore the structure implicit in the tensor product, where we are likely to want to know how the surface estimated by the Duchon spline ofx
andy
smoothly varies withz
. Previouslysmooth_estimates()
would generate surfaces ofz
andx
, varying byy
. Now,smooth_estimates()
correctly identifies that one of the marginal smooths of the tensor product is a 2D surface and will focus on that surface varying with the other terms in the tensor product.This improved behaviour is needed because in some
bam()
models it is not always possible to do the obvious thing and reorder the smooths when defining the tensor product to bete(x, y, z, bs = c(ds, cr), d = c(2, 1))
. Whendiscrete = TRUE
is used withbam()
the terms in the tensor product may get rearranged during model setup for maximum efficiency (See Details in?mgcv::bam
).Additionally,
draw.gam()
now also works the same way. New function
null_deviance()
that extracts the null deviance of a fitted model.draw()
,smooth_estimates()
,fitted_values()
,data_slice()
, andsmooth_samples()
now all work for models fitted withscam::scam()
. Where it matters, current support extends only to univariate smooths.generate_draws()
is a new lowlevel function for generating posterior draws from fitted model coefficients.generate_daws()
is an S3 generic function so is extensible by users. Currently provides a simple interface to a simple Gaussian approximation sampler (gaussian_draws()
) and the simple Metropolis Hasting sample (mh_draws()
) available viamgcv::gam.mh()
. #211smooth_label()
is a new function for extracting the labels ‘mgcv’ creates for smooths from the smooth object itself.penalty()
has a default method that works withs()
,te()
,t2()
, andti()
, which create a smooth specification.transform_fun()
gains argumentconstant
to allow for the addition of a constant value to objects (e.g. the estimate and confidence interval). This enables a singleobj > transform_fun(fun = exp, constant = 5)
instead of separate calls toadd_constant()
and thentransform_fun()
. Part of the discussion of #79model_constant()
is a new function that simply extracts the first coefficient from the estimated model.
Bug fixes

link()
,inv_link()
, and related family functions for theocat()
weren’t correctly identifying the family name and as a result would throw an error even when passed an object of the correct family.link()
andinv_link()
now work correctly for thebetar()
family in a fitted GAM. The
print()
method forlp_matrix()
now converts the matrix to a data frame before conversion to a tibble. This makes more sense as it results in more typical behaviour as the columns of the printed object are doubles.Constrained factor smooths (
bs = "sz"
) where the factor is not the first variable mentioned in the smooth (i.e.s(x, f, bs = "sz")
for continuousx
and factorf
) are now plotable withdraw()
. #208parametric_effects()
was unable to handle special parametric terms likepoly(x)
orlog(x)
in formulas. Reported by @fhui28 #212parametric_effects()
now works better for location, scale, shape models. Reported by @pboesu #45parametric_effects
now works when there are missing values in one or more variables used in a fitted GAM. #219response_derivatives()
was incorrectly using.data
with tidyselect selectors.typical_values()
could not handle logical variables in a GAM fit as mgcv stores these as numerics in thevar.summary
. This affectedevenly()
anddata_slice()
. #222parametric_effects()
would fail when two or more ordered factors were in the model. Reported by @dsmi31 #221Continuous by smooths were being evaluated with the median value of the
by
variable instead of a value of 1. #224fitted_samples()
(and henceposterior_samples()
) now handles models with offset terms in the formula. Offset terms supplied via theoffset
argument are ignored bymgcv:::predict.gam()
and hence are ignored also bygratia
. Reported by @jonathonmellor #231 #233smooth_estimates()
would fail on a"fs"
smooth when a multivariate base smoother was used and the factor was not the last variable specified in the definition of the smooth:s(x1, x2, f, bs = "fs", xt = list(bs = "ds"))
would work, buts(f, x1, x2, bs = "fs", xt = list(bs = "ds"))
(or any ordering of variables that places the factor not last) would emit an obscure error. The ordering of the terms involved in the smooth now doesn’t matter. Reported by @chrisaak #249.draw.gam()
would fail when plotting a multivariate base smoother used in an"sz"
smooth. Now, this use case is identified and a message printed indicating that (currently) gratia doesn’t know how to plot such a smooth. Reported by @chrisaak #249.draw.gam()
would fail when plotting a multivariate base smoother used in an"fs"
smooth. Now, this use case is identified and a message printed indicating that (currently) gratia doesn’t know how to plot such a smooth. Reported by @chrisaak #249.derivative_samples()
would fail withorder = 2
and was only computing forward finite differences, regardless oftype
fororder = 1
. Partly reported by @samlipworth #251.The
draw()
method forpenalty()
was normalizing the penalty to the range 0–1, not the claimed and documented 1–1 with argumentnormalize = TRUE
. This is now fixed.smooth_samples()
was failing whendata
was supplied that contained more variables than were used in the smooth that was being sampled. Hence this generally fail unless a single smooth was being sampled from or the model contained only a single smooth. The function never intended to retain all the variables indata
but was written in such a way that it would fail when relocating the data columns to the end of the posterior sampling object. #255draw.gam()
anddraw.smooth_estimates()
would fail when plotting a univariate tensor product smooth (e.g.te(x)
,ti(x)
, ort2()
). Reported by @wStockhausen #260plot.smooth()
was not printing the factor level in subtitles for ordered factor by smooths.
gratia 0.8.1
CRAN release: 20230202
User visible changes
smooth_samples()
now returns objects with variables involved in smooths that have their correct name. Previously variables were named.x1
,.x2
, etc. Fixing #126 and improving compatibility withcompare_smooths()
andsmooth_estimates()
allowed the variables to be named correctly.gratia now depends on version 1.841 or later of the mgcv package.
New features

draw.gam()
can now handle tensor products that include a marginal random effect smooth. Beware plotting such smooths if there are many levels, however, as a separate surface plot will be produced for each level.
Bug fixes
Additional fixes for changes in dplyr 1.1.0.
smooth_samples()
now works when sampling from posteriors of multiple smooths with different dimension. #126 reported by @Aariq
gratia 0.8.0
User visible changes
{gratia} now depends on R version 4.1 or later.
A new vignette “Data slices” is supplied with {gratia}.

Functions in {gratia} have harmonised to use an argument named
data
instead ofnewdata
for passing new data at which to evaluate features of smooths. A message will be printed ifnewdata
is used from now on. Existing code does not need to be changed asdata
takes its value fromnewdata
.Note that due to the way
...
is handled in R, if your R script uses thedata
argument, and is run with versions of gratia prior to 8.0 (when released; 0.7.3.8 if using the development version) the usersupplied data will be silently ignored. As such, scripts usingdata
should check that the installed version of gratia is >= 0.8 and package developers should update to depend on versions >= 0.8 by usinggratia (>= 0.8)
inDESCRIPTION
. The order of the plots of smooths has changed in
draw.gam()
so that they again match the order in which smooths were specified in the model formula. See Bug Fixes below for more detail or #154.
New features
Added basic support for GAMLSS (distributional GAMs) fitted with the
gamlss()
function from package GJRM. Support is currently restricted to adraw()
method.
difference_smooths()
can now include the group means in the difference, which many users expected. To include the group means usegroup_means = TRUE
in the function call, e.g.difference_smooths(model, smooth = "s(x)", group_means = TRUE
). Note: this function still differs fromplot_diff()
in package itsadug, which essentially computes differences of model predictions. The main practical difference is that other effects beyond the factor by smooth, including random effects, may be included withplot_diff()
.This implements the main wish of #108 (@dinga92) and #143 (@mbolyanatz) despite my protestations that this was complicated in some cases (it isn’t; the complexity just cancels out.)

data_slice()
has been totally revised. Now, the user provides the values for the variables they want in the slice and any variables in the model that are not specified will be held at typical values (i.e. the value of the observation that is closest to the median for numeric variables, or the modal factor level.)Data slices are now produced by passing
name
=value
pairs for the variables and their values that you want to appear in the slice. For examplem < gam(y ~ s(x1) + x2 + fac) data_slice(model, x1 = evenly(x1, n = 100), x2 = mean(x2))
The
value
in the pair can be an expression that will be looked up (evaluated) in thedata
argument or the model frame of the fitted model (the default). In the above example, the resulting slice will be a data frame of 100 observations, comprisingx1
, which is a vector of 100 values spread evenly over the range ofx1
, a constant value of the mean ofx2
for thex2
variable, and a constant factor level, the model class offac
, for thefac
variable of the model. partial_derivatives()
is a new function for computing partial derivatives of multivariate smooths (e.g.s(x,z)
,te(x,z)
) with respect to one of the margins of the smooth. Multivariate smooths of any dimension are handled, but only one of the dimensions is allowed to vary. Partial derivatives are estimated using the method of finite differences, with forward, backward, and central finite differences available. Requested by @noamross #101overview()
provides a simple overview of model terms for fitted GAMs.The new
bs = "sz"
basis that was released with mgcv version 1.1841 is now supported insmooth_estimates()
,draw.gam()
, anddraw.smooth_estimates()
and this basis has its own unique plotting method. #202
basis()
now has a method for fitted GAM(M)s which can extract the estimated basis from the model and plot it, using the estimated coefficients for the smooth to weight the basis. #137There is also a new
draw.basis()
method for plotting the results of a call tobasis()
. This method can now also handle bivariate bases.tidy_basis()
is a lower level function that does the heavy lifting inbasis()
, and is now exported.tidy_basis()
returns a tidy representation of a basis supplied as an object inheriting from class"mgcv.smooth"
. These objects are returned in the$smooth
component of a fitted GAM(M) model. lp_matrix()
is a new utility function to quickly return the linear predictor matrix for an estimated model. It is a wrapper topredict(..., type = "lpmatrix")
evenly()
is a synonym forseq_min_max()
and is preferred going forward. Gains argumentby
to produce sequences over a covariate that increment in units ofby
.ref_level()
andlevel()
are new utility functions for extracting the reference or a specific level of a factor respectively. These will be most useful when specifying covariate values to condition on in a data slice.model_vars()
is a new, public facing way of returning a vector of variables that are used in a model.difference_smooths()
will now use the usersupplied data as points at which to evaluate a pair of smooths. Also note that the argumentnewdata
has been renameddata
. #175The
draw()
method fordifference_smooths()
now uses better labels for plot titles to avoid long labels with even modest factor levels.derivatives()
now works for factorsmooth interaction ("fs"
) smooths.draw()
methods now allow the angle of tick labels on the x axis of plots to be rotated using argumentangle
. Requested by @tamasferenci #87draw.gam()
and related functions (draw.parametric_effects()
,draw.smooth_estimates()
) now add the basis to the plot using a caption. #155smooth_coefs()
is a new utility function for extracting the coefficients for a particular smooth from a fitted model.smooth_coef_indices()
is an associated function that returns the indices (positions) in the vector of model coefficients (returned bycoef(gam_model)
) of those coefficients that pertain to the stated smooth.draw.gam()
now better handles patchworks of plots where one or more of those plots has fixed aspect ratios. #190
Bug fixes
draw.posterior_smooths
now plots posterior samples with a fixed aspect ratio if the smooth is isotropic. #148derivatives()
now ignores random effect smooths (for which derivatives don’t make sense anyway). #168confint.gam(...., method = "simultaneous")
now works with factor by smooths whereparm
is passed the full name of a specific smooths(x)faclevel
.The order of plots produced by
gratia::draw.gam()
again matches the order in which the smooths entered the model formula. Recent changes to the internals ofgratia::draw.gam()
when the switch tosmooth_estimates()
was undertaken lead to a change in behaviour resulting from the use ofdplyr::group_split()
, and it’s coercion internally of a character vector to a factor. This factor is now created explicitly, and the levels set to the correct order. #154Setting the
dist
argument to set response or smooth values toNA
if they lay too far from the support of the data in multivariate smooths, this would lead an incorrect scale for the response guide. This is now fixed. #193Argument
fun
todraw.gam()
was not being applied to any parametric terms. Reported by @grasshoppermouse #195draw.gam()
was adding the uncertainty for all linear predictors to smooths whenoverall_uncertainty = TRUE
was used. Nowdraw.gam()
only includes the uncertainty for those linear predictors in which a smooth takes part. #158partial_derivatives()
works when provided with a single data point at which to evaluate the derivative. #199transform_fun.smooth_estimates()
was addressing the wrong variable names when trying to transform the confidence interval. #201data_slice()
doesn’t fail with an error when used with a model that contains an offset term. #198confint.gam()
no longer usesevaluate_smooth()
, which is soft deprecated. #167qq_plot()
andworm_plot()
could compute the wrong deviance residuals used to generate the theoretical quantiles for some of the more exotic families (distributions) available in mgcv. This also affectedappraise()
but only for the QQ plot; the residuals shown in the other plots and the deviance residuals shown on the yaxis of the QQ plot were correct. Only the generation of the reference intervals/quantiles was affected.
gratia 0.7.3
CRAN release: 20220509
User visible changes
 Plots of smooths now use “Partial effect” for the yaxis label in place of “Effect”, to better indicate what is displayed.
New features
confint.fderiv()
andconfint.gam()
now return their results as a tibble instead of a commonorgarden data frame. The latter mostly already did this.Examples for
confint.fderiv()
andconfint.gam()
were reworked, in part to remove some inconsistent output in the examples when run on M1 macs.
Bug fixes

compare_smooths()
failed when passed nonstandard model “names” likecompare_smooths(m_gam, m_gamm$gam)
orcompare_smooths(l[[1]], l[[2]])
even if the evaluated objects were valid GAM(M) models. Reported by Andrew Irwin #150
gratia 0.7.2
CRAN release: 20220317
New features
draw.gam()
anddraw.smooth_estimates()
can now handle splines on the sphere (s(lat, long, bs = "sos")
) with special plotting methods usingggplot2::coord_map()
to handle the projection to spherical coordinates. An orthographic projection is used by default, with an essentially arbitrary (and northern hemispherecentric) default for the orientation of the view.fitted_values()
insures thatdata
(and hence the returned object) is a tibble rather than a common or garden data frame.
Bug fixes
draw.posterior_smooths()
was redundantly plotting duplicate data in the rug plot. Now only the unique set of covariate values are used for drawing the rug.data_sim()
was not passing thescale
argument in the bivariate example setting ("eg2"
).draw()
methods forgamm()
andgamm4::gamm4()
fits were not passing arguments on todraw.gam()
.draw.smooth_estimates()
would produce a subtitle with data for a continuous by smooth as if it were a factor by smooth. Now the subtitle only contains the name of the continuous by variable.
gratia 0.7.1
Due to an issue with the size of the package source tarball, which wasn’t discovered until after submission to CRAN, 0.7.1 was never released.
New features

draw.gam()
anddraw.smooth_estimates()
: {gratia} can now handle smooths of 3 or 4 covariates when plotting. For smooths of 3 covariates, the third covariate is handled withggplot2::facet_wrap()
and a set (defaultn
= 16) of small multiples is drawn, each a 2d surface evaluated at the specified value of the third covariate. For smooths of 4 covariates,ggplot2::facet_grid()
is used to draw the small multiples, with the default producing 4 rows by 4 columns of plots at the specific values of the third and fourth covariates. The number of small multiples produced is controlled by new argumentsn_3d
(default =n_3d = 16
) andn_4d
(defaultn_4d = 4
, yieldingn_4d * n_4d
= 16 facets) respectively.This only affects plotting;
smooth_estimates()
has been able to handle smooths of any number of covariates for a while.When handling higherdimensional smooths, actually drawing the plots on the default device can be slow, especially with the default value of
n = 100
(which for 3D or 4D smooths would result in 160,000 data points being plotted). As such it is recommended that you reducen
to a smaller value:n = 50
is a reasonable compromise of resolution and speed. model_concurvity()
returns concurvity measures frommgcv::concurvity()
for estimated GAMs in a tidy format. The synonymconcrvity()
is also provided. Adraw()
method is provided which produces a bar plot or a heatmap of the concurvity values depending on whether the overall concurvity of each smooth or the pairwise concurvity of each smooth in the model is requested.draw.gam()
gains argumentresid_col = "steelblue3"
that allows the colour of the partial residuals (if plotted) to be changed.
Bug fixes
model_edf()
was not using thetype
argument. As a result it only ever returned the default EDF type.add_constant()
methods weren’t applying the constant to all the required variables.draw.gam()
,draw.parametric_effects()
now actually work for a model with only parametric effects. #142 Reported by @NelsonGonparametric_effects()
would fail for a model with only parametric terms becausepredict.gam()
returns empty arrays when passedexclude = character(0)
.
gratia 0.7.0
CRAN release: 20220207
Major changes

draw.gam()
now usessmooth_estimates()
internally and consequently uses itsdraw()
method and underlying plotting code. This has simplified the code compared toevaluate_smooth()
and its methods, which will allow for future development and addition of features more easily than ifevaluate_smooth()
had been retained.Similarly,
evaluate_parametric_terms()
is now deprecated in favour ofparametric_effects()
, which is also used internally bydraw.gam()
if parametric terms are present in the model (andparametric = TRUE
).While a lot of code has been reused so differences between plots as a result of this change should be minimal, some corner cases may have been missed. File an Issue if you notice something that has changed that you think shouldn’t.
draw.gam()
now plots 2D isotropic smooths (TPRS and Duchon splines) with equallyscaled x and y coordinates usingcoord_equal(ratio = 1)
. Alignment of these plots will be a little different now when plotting models with multiple smooths. See Issue #81.
Deprecated functions
From version 0.7.0, the following functions are considered deprecated and their use is discouraged:

fderiv()
is softdeprecated in favour ofderivatives()
, 
evaluate_smooth()
is softdeprecated in favour ofsmooth_estimates()
, 
evaluate_parametric_term()
is softdeprecated in favour ofparametric_effects()
.
The first call to one of these functions will generate a warning, pointing to the newer, alternative, function. It is safe to ignore these warnings, but these deprecated functions will no longer receive updates and are thus at risk of being removed from the package at some future date. The newer alternatives can handle more types of models and smooths, especially so in the case of smooth_estimates()
.
New features

fitted_values()
provides a tidy wrapper aroundpredict.gam()
for generating fitted values from the model. New covariate values can be provided via argumentdata
. A credible interval on the fitted values is returned, and values can be on the link (linear predictor) or response scale.Note that this function returns expected values of the response. Hence, “fitted values” is used instead of “predictions” in the case of new covariate values to differentiate these values from the case of generating new response values from a fitted model.
rootogram()
and itsdraw()
method produce rootograms as diagnostic plots for fitted models. Currently only for models fitted withpoisson()
,nb()
,negbin()
,gaussian()
families.
New helper functions
typical_values()
,factor_combos()
anddata_combos()
for quickly creating data sets for producing predictions from fitted models where some covariatess are fixed at come typical or representative values.typical_values()
is a new helper function to return typical values for the covariates of a fitted model. It returns the value of the observation closest to the median for numerical covariates or the modal level of a factor while preserving the levels of that factor.typical_values()
is useful in preparing data slices or scenarios for which fitted values from the estimated model are required.factor_combos()
extracts and returns the combinations of levels of factors found in data used to fit a model. Unliketypical_values()
,factor_combos()
returns all the combinations of factor levels observed in the data, not just the modal level. Optionally, all combinations of factor levels can be returned, not just those in the observed data.data_combos()
combines returns the factor data fromfactor_combos()
plus the typical values of numerical covariates. This is useful if you want to generate predictions from the model for each combination of factor terms while holding any continuous covariates at their median values. nb_theta()
is a new extractor function that returns the theta parameter of a fitted negative binomial GAM (familiesnb()
ornegbin()
). Additionally,theta()
andhas_theta()
provide additional functionality.theta()
is an experimental function for extracting any additional parameters from the model or family.has_theta()
is useful for checking if any additional parameters are available from the family or model.edf()
extracts the effective degrees of freedom (EDF) of a fitted model or a specific smooth in the model. Various forms for the EDF can be extracted.model_edf()
returns the EDF of the overall model. If supplied with multiple models, the EDFs of each model are returned for comparison.
draw.gam()
can now show a “rug” plot on a bivariate smooth by drawing small points with high transparency over the smooth surface at the data coordinates.In addition, the rugs on plots of factor by smooths now show the locations of covariate values for the specific level of the factor and not over all levels. This better reflects what data were used to estimate the smooth, even though the basis for each smooth was set up using all of the covariate locations.
draw.gam()
anddraw.smooth_estimates()
now allow some aspects of the plot to be changed: the fill (but not colour) and alpha attributes of the credible interval, and the line colour for the smooth can now be specified using argumentsci_col
,ci_alpha
, andsmooth_col
respectively.Partial residuals can now be plotted on factor by smooths. To allow this, the partial residuals are filtered so that only residuals associated with a particular level’s smooth are drawn on the plot of the smooth.
smooth_estimates()
usescheck_user_select_smooths()
to handle userspecified selection of smooth terms. As such it is more flexible than previously, and allows for easier selection of smooths to evaluate.fixef()
is now imported (and reexported) from the nlme package, with methods for models fitted withgam()
andgamm()
, to extract fixed effects estimates from fitted models.fixed_effects()
is an alias forfixef()
.The
draw()
method forsmooth_samples()
can now handle 2D smooths. Additionally, the number of posterior draws to plot can now be specified when plotting using new argumentn_samples
, which will result inn_samples
draws being selected at random from the set of draws for plotting. New argumentseed
allows the selection of draws to be repeatable.
Bug fixes
smooth_estimates()
was not filtering usersupplied data for the by level of the specific smooth when used with by factor smooths. This would result in the smooth being evaluated at all rows of the usersupplied data, and therefore would result innrow(user_data) * nlevels(by_variable)
rows in the returned object instead ofnrow(user_data)
rows.The
add_confint()
method forsmooth_estimates()
had the upper and lower intervals reversed. #107 Reported by @Aariqdraw.gam()
andsmooth_estimates()
were both ignoring thedist
argument that allows covariate values that lie too far from the support of the data to be excluded when returning estimated values from the smooth and plotting it. #111 Reported by @Aariqsmooth_samples()
with a factor by GAM would return samples for the first factor level only. Reported by @rroyaute in discussion of #121smooth_samples()
would fail if the model contained random effect “smooths”. These are now ignored with a message when runningsmooth_samples()
. Reported by @isabellaghement in #121link()
,inv_link()
were failing on models fitted withfamily = scat()
. Reported by @Aariq #130
gratia 0.6.0
CRAN release: 20210418
Major changes

The {cowplot} package has been replaced by the {patchwork} package for producing multipanel figures in
draw()
andappraise()
. This shouldn’t affect any code that used {gratia} only, but if you passed additional arguments tocowplot::plot_grid()
or used thealign
oraxis
arguments ofdraw()
andappraise()
, you’ll need to adapt code accordingly.Typically, you can simply delete the
align
oraxis
arguments and {patchwork} will just work and align plots nicely. Any arguments passed via...
tocowplot::plot_grid()
will just be ignored bypatchwork::wrap_plots()
unless those passed arguments match any of the arguments ofpatchwork::wrap_plots()
.
New features
The {patchwork} package is now used for multipanel figures. As such, {gratia} no longer Imports from the {cowplot} package.

Worm plot diagnostic plots are available via new function
worm_plot()
. Worm plots are detrended QQ plots, where deviation from the QQ reference line are emphasized as deviations around the line occupy the full height of the plot.worm_plot()
methods are available for models of classes"gam"
,"glm"
, and"lm"
. (#62) 
Smooths can now be compared across models using
compare_smooths()
, and comparisons visualised with the associateddraw()
method. (#85 @dill)This feature is a bit experimental; the returned object uses nested lists and may change in the future if users find this confusing.
The reference line in
qq_plot()
withmethod = "normal"
was previously drawn as a line with intercept 0 and slope 1, to match the other methods. This was inconsistent withstats::qqplot()
which drew the line through the 1st and 3rd quartiles.qq_plot()
withmethod = "normal"
now uses this robust reference line. Reference lines for the other methods remain drawn with slope 1 and intercept 0.qq_plot()
withmethod = "normal"
now draws a pointwise reference band using the standard error of the order statistic.The
draw()
method forpenalty()
now plots the penalty matrix heatmaps in a morelogical orientation, to match how the matrices might be written down or printed to the R console.link()
, andinv_link()
now work for models fitted with thegumbls()
andshash()
families. (#84)extract_link()
is a lower level utility function related tolink()
andinv_link()
, and is now exported.
User visible changes
The default method name for generating reference quantiles in
qq_plot()
was changed from"direct"
to"uniform"
, to avoid confusion with themgcv::qq.gam()
help page description of the methods. Accordingly usingmethod = "direct"
is deprecated and a message to this effect is displayed if used.The way smooths/terms are selected in
derivatives()
has been switched to use the same mechanism asdraw.gam()
’sselect
argument. To get a partial match toterm
, you now need to also specifypartial_match = TRUE
in the call toderivatives()
.
Bug fixes
transform_fun()
had a copy paste bug in the definition of the then generic. (#96 @Aariq)derivatives()
with usersuppliednewdata
would fail for factor by smooths withinterval = "simultaneous"
and would introduce rows with derivative == 0 withinterval = "confidence"
because it didn’t subset the rows ofnewdata
for the specific level of the by factor when computing derivatives. (#102 @sambweber)evaluate_smooth()
can now handle random effect smooths defined using an ordered factor. (#99 @StefanoMezzini)
gratia 0.5.1
CRAN release: 20210123
New features

smooth_estimates()
can now handle 
penalty()
provides a tidy representation of the penalty matrices of smooths. The tidy representation is most suitable for plotting withggplot()
.A
draw()
method is provided, which represents the penalty matrix as a heatmap.
User visible changes
 The
newdata
argument tosmooth_estimates()
has been changed todata
as was originally intended.
gratia 0.5.0
CRAN release: 20210110
New features

Partial residuals for models can be computed with
partial_residuals()
. The partial residuals are the weighted residuals of the model added to the contribution of each smooth term (as returned bypredict(model, type = "terms")
.Also, new function
add_partial_residuals()
can be used to add the partial residuals to data frames. 
Users can now control to some extent what colour or fill scales are used when plotting smooths in those
draw()
methods that use them. This is most useful to change the fill scale when plotting 2D smooths, or to change the discrete colour scale used when plotting random factor smooths (bs = "fs"
).The user can pass scales via arguments
discrete_colour
andcontinuous_fill
. 
The effects of certain smooths can be excluded from data simulated from a model using
simulate.gam()
andpredicted_samples()
by passingexclude
orterms
on topredict.gam()
. This allows for excluding random effects, for example, from model predicted values that are then used to simulate new data from the conditional distribution. See the example inpredicted_samples()
.Wish of #74 (@hgoldspiel)

draw.gam()
and related functions gain argumentsconstant
andfun
to allow for userdefined constants and transformations of smooth estimates and confidence intervals to be applied.Part of wish of Wish of #79.
confint.gam()
now works for 2D smooths also.smooth_estimates()
is an early version of code to replace (or more likely supersede)evaluate_smooth()
.smooth_estimates()
can currently only handle 1D smooths of the standard types.
User visible changes

The meaning of
parm
inconfint.gam
has changed. This argument now requires a smooth label to match a smooth. A vector of labels can be provided, but partial matching against a smooth label only works with a singleparm
value.The default behaviour remains unchanged however; if
parm
isNULL
then all smooths are evaluated and returned with confidence intervals. data_class()
is no longer exported; it was only ever intended to be an internal function.
Bug Fixes

confint.gam()
was failing on a tensor product smooth due to matching issues. Reported by @tamasferenci #88This also fixes #80
 which was a related issue with selecting a specific smooth.
The vdiffr package is now used conditionally in package tests. Reported by Brian Ripley #93
gratia 0.4.1
CRAN release: 20200530
User visible changes

draw.gam()
withscales = "fixed"
now applies to all terms that can be plotted, including 2d smooths.Reported by @StefanoMezzini #73
Bug fixes
dplyr::combine()
was deprecated. Switch tovctrs::vec_c()
.
draw.gam()
withscales = "fixed"
wasn’t using fixed scales where 2d smooths were in the model.Reported by @StefanoMezzini #73
gratia 0.4.0
New features
draw.gam()
can include partial residuals when drawing univariate smooths. Useresiduals = TRUE
to add partial residuals to each univariate smooth that is drawn. This feature is not available for smooths of more than one variable, by smooths, or factorsmooth interactions (bs = "fs"
).
The coverage of credible and confidence intervals drawn by
draw.gam()
can be specified via argumentci_level
. The default is arbitrarily0.95
for no other reason than (rough) compatibility withplot.gam()
.This change has had the effect of making the intervals slightly narrower than in previous versions of gratia; intervals were drawn at ± 2 × the standard error. The default intervals are now drawn at ± ~1.96 × the standard error.
New function
difference_smooths()
for computing differences between factor smooth interactions. Methods available forgam()
,bam()
,gamm()
andgamm4::gamm4()
. Also has adraw()
method, which can handle differences of 1D and 2D smooths currently (handling 3D and 4D smooths is planned).New functions
add_fitted()
andadd_residuals()
to add fitted values (expectations) and model residuals to an existing data frame. Currently methods available for objects fitted bygam()
andbam()
.data_sim()
is a tidy reimplementation ofmgcv::gamSim()
with the added ability to use sampling distributions other than the Gaussian for all models implemented. Currently Gaussian, Poisson, and Bernoulli sampling distributions are available.smooth_samples()
can handle continuous by variable smooths such as in varying coefficient models.link()
andinv_link()
now work for all families available in mgcv, including the location, scale, shape families, and the more specialised families described in?mgcv::family.mgcv
.evaluate_smooth()
,data_slice()
,family()
,link()
,inv_link()
methods for models fitted usinggamm4()
from the gamm4 package.data_slice()
can generate data for a 1d slice (a single variable varying).
The colour of the points, reference lines, and simulation band in
appraise()
can now be specified via arguments
point_col
, 
point_alpha
, ci_col
ci_alpha
line_col
These are passed on to
qq_plot()
,observed_fitted_plot()
,residuals_linpred_plot()
, andresiduals_hist_plot()
, which also now take the new arguments were applicable. 
Added utility functions
is_factor_term()
andterm_variables()
for working with models.is_factor_term()
identifies is the named term is a factor using information from theterms()
object of the fitted model.term_variables()
returns a character vector of variable names that are involved in a model term. These are strictly for working with parametric terms in models.
appraise()
now works for models fitted byglm()
andlm()
, as do the underlying functions it calls, especiallyqq_plot
.appraise()
also works for models fitted with familygaulss()
. Further location scale models and models fitted with extended family functions will be supported in upcoming releases.
User visible changes
datagen()
is now an internal function and is no longer exported. Usedata_slice()
instead.evaluate_parametric_term()
is now much stricter and can only evaluate main effect terms, i.e. those whose order, as stored in theterms
object of the model is1
.
Bug fixes
The
draw()
method forderivatives()
was not getting the xaxis label for factor by smooths correctly, and instead was usingNA
for the second and subsequent levels of the factor.The
datagen()
method for class"gam"
couldn’t possibly have worked for anything but the simplest models and would fail even with simple factor by smooths. These issues have been fixed, but the behaviour ofdatagen()
has changed, and the function is now not intended for use by users.Fixed an issue where in models terms of the form
factor1:factor2
were incorrectly identified as being numeric parametric terms. #68
gratia 0.3.1
CRAN release: 20200329
New features

New functions
link()
andinv_link()
to access the link function and its inverse from fitted models and family functions.Methods for classes:
"glm"
,"gam"
,"bam"
,"gamm"
currently. #58 Adds explicit
family()
methods for objects of classes"gam"
,"bam"
, and"gamm"
.derivatives()
now handles nonnumeric when creating shifted data for finite differences. Fixes a problem withstringsAsFactors = FALSE
default in Rdevel. #64
gratia 0.3.0
CRAN release: 20200119
New features

gratia now uses the mvnfast package for random draws from a multivariate normal distribution (
mvnfast::rmvn()
). Contributed by Henrik Singmann New function
basis()
for generating tidy representations of basis expansions from an mgcvlike definition of a smooth, e.g.s()
,te()
,ti()
, ort2()
. The basic smooth types also have a simpledraw()
method for plotting the basis.basis()
is a simple wrapper aroundmgcv::smoothCon()
with some post processing of the basis model matrix into a tidy format. #42New function
smooth_samples()
to draw samples of entire smooth functions from their posterior distribution. Also has adraw()
method for plotting the posterior samples.
Bug fixes
draw.gam()
would produce empty plots between the panels for the parametric terms if there were 2 or more parametric terms in a model. Reported by @sklayn #39.
derivatives()
now works with factor by smooths, including ordered factor by smooths. The function also now works correctly for complex models with multiple covariates/smooths. #47derivatives()
also now handles'fs'
smooths. Reported by @tomanduio #57. evaluate_parametric_term()
and hencedraw.gam()
would fail on aziplss()
model because i) gratia didn’t handle parametric terms in models with multiple linear predictors correctly, and ii) gratia didn’t convert to the naming convention of mgcv for terms in higher linear predictors. Reported by @pboesu #45