# we acknowledge that this figure is based on:# https://stackoverflow.com/questions/65918325/how-to-plot-surface-fit-through-3d-data-in-r# also, of potential interest:# https://stackoverflow.com/questions/50573936/r-how-to-change-color-of-plotly-3d-surfacelibrary(mgcv)library(plotly)library(here)library(htmlwidgets)# fit a gam modelmod <-gam(qsec ~te(hp) +te(wt) +ti(hp, wt), data = mtcars)# make some predictions for the model at different combinations of hp and wthp_seq <-seq(min(mtcars$hp, na.rm =TRUE), max(mtcars$hp, na.rm=TRUE), length =25)wt_seq <-seq(min(mtcars$wt, na.rm =TRUE), max(mtcars$wt, na.rm=TRUE), length =25)# make a function that will generate predictionspredfun <-function(x, y){ newdat <-data.frame(hp = x, wt = y)predict(mod, newdata = newdat)}# we apply that prediction function to the sequences of data we made abovefit <-outer(hp_seq, wt_seq, Vectorize(predfun))# set axes title# https://plotly.com/r/3d-axes/axx <-list(title ="Composition")axy <-list(title ="Distribution")axz <-list(title ="Structure")# ticks formattingaxx <-list(title ="Composition – Lack of adaptive capacity",ticketmode ='array',ticktext =c("High", "Low"),tickvals =c(50, 300))axy <-list(title ="Distribution – Exposure",ticktext =c("Low", "High"),tickvals =c(2, 5))axz <-list(title ="Structure – Sensitivity",ticktext =c("Low", "High"),tickvals =c(14, 24))# put everything together# https://hauselin.github.io/colorpalettejs/fig <-plot_ly() |>add_surface(x =~hp_seq, y =~wt_seq, z =t(fit), showscale =FALSE# colorscale = list(c(0, 1), c("#440154", "#fde725")) ) |>layout(scene =list(xaxis = axx, yaxis = axy,zaxis = axz))fig