Plot Surface for Interaction Effects
plot_surface.RdGenerates a 3D surface plot to visualize the interaction effect of two variables (x and z)
on an outcome (y)
using parameter estimates from a supported model object (e.g., lavaan or modsem).
The function allows specifying ranges for x and z in standardized z-scores, which are then transformed
back to the original scale based on their means and standard deviations.
Usage
plot_surface(
  x,
  z,
  y,
  model,
  min_x = -3,
  max_x = 3,
  min_z = -3,
  max_z = 3,
  standardized = FALSE,
  detail = 0.01,
  xz = NULL,
  colorscale = "Viridis",
  reversescale = FALSE,
  showscale = TRUE,
  cmin = NULL,
  cmax = NULL,
  surface_opacity = 1,
  grid = FALSE,
  grid_nx = 12,
  grid_ny = 12,
  grid_color = "rgba(0,0,0,0.45)",
  group = NULL,
  ...
)Arguments
- x
 A character string specifying the name of the first predictor variable.
- z
 A character string specifying the name of the second predictor variable.
- y
 A character string specifying the name of the outcome variable.
- model
 A model object of class
modsem_pi,modsem_da,modsem_mplus, orlavaan. The model should include paths for the predictors (x,z, andxz) to the outcome (y).- min_x
 Numeric. Minimum value of
xin z-scores. Default is -3.- max_x
 Numeric. Maximum value of
xin z-scores. Default is 3.- min_z
 Numeric. Minimum value of
zin z-scores. Default is -3.- max_z
 Numeric. Maximum value of
zin z-scores. Default is 3.- standardized
 Should coefficients be standardized beforehand?
- detail
 Numeric. Step size for the grid of
xandzvalues, determining the resolution of the surface. Smaller values increase plot resolution. Default is1e-2.- xz
 Optional. A character string or vector specifying the interaction term between
xandz. IfNULL, the interaction term is constructed aspaste(x, z, sep = ":")and adjusted for specific model classes.- colorscale
 Character or list. Colorscale used to color the surface. - Default is
"Viridis", which matches the classic Plotly default. - Can be a built-in palette name (e.g.,"Greys","Plasma","Turbo"), or a custom two-column list with numeric stops (0–1) and color codes. Example custom scale:list(c(0, "white"), c(1, "black"))for a black-and-white gradient.- reversescale
 Logical. If
TRUE, reverses the color mapping so that low values become high colors and vice versa. Default isFALSE.- showscale
 Logical. If
TRUE, displays the colorbar legend alongside the plot. Default isTRUE.- cmin
 Numeric or
NULL. The minimum value for the colorscale mapping. IfNULL, the minimum of the data (proj_y) is used automatically. Use this to standardize the color range across multiple plots.- cmax
 Numeric or
NULL. The maximum value for the colorscale mapping. IfNULL, the maximum of the data (proj_y) is used automatically. Use this to standardize the color range across multiple plots.- surface_opacity
 Numeric (0–1). Controls the opacity of the surface. -
1= fully opaque (default) -0= fully transparent Useful when overlaying multiple surfaces or highlighting gridlines.- grid
 Logical. If
TRUE, draws gridlines (wireframe) directly on the surface using Plotly's contour features. Default isFALSE.- grid_nx
 Integer. Approximate number of gridlines to draw along the **x-axis** direction when
grid = TRUE. Higher values create a denser grid. Default is12.- grid_ny
 Integer. Approximate number of gridlines to draw along the **y-axis** direction when
grid = TRUE. Higher values create a denser grid. Default is12.- grid_color
 Character. Color of the gridlines drawn on the surface. Must be a valid CSS color string, including
rgba()for transparency. - Default is"rgba(0,0,0,0.45)"(semi-transparent black). Example:"rgba(255,255,255,0.8)"for semi-transparent white lines.- group
 Which group to create surface plot for. Only relevant for multigroup models. Must be an integer index, representing the nth group.
- ...
 Additional arguments passed to
plotly::plot_ly.
Value
A plotly surface plot object displaying the predicted values of y across the grid of x and z values.
  The color bar shows the values of y.
Details
The input min_x, max_x, min_z, and max_z define the range of x and z values in z-scores.
These are scaled by the standard deviations and shifted by the means of the respective variables, obtained
from the model parameter table. The resulting surface shows the predicted values of y over the grid of x and z.
The function supports models of class modsem (with subclasses modsem_pi, modsem_da, modsem_mplus) and lavaan.
For lavaan models, it is not designed for multigroup models, and a warning will be issued if multiple groups are detected.
Note
The interaction term (xz) may need to be manually specified for some models. For non-lavaan models,
interaction terms may have their separator (:) removed based on circumstances.
Examples
m1 <- "
# Outer Model
  X =~ x1 + x2 + x3
  Z =~ z1 + z2 + z3
  Y =~ y1 + y2 + y3
# Inner model
  Y ~ X + Z + X:Z
"
est1 <- modsem(m1, data = oneInt)
plot_surface("X", "Z", "Y", model = est1)
# \dontrun{
tpb <- "
# Outer Model (Based on Hagger et al., 2007)
  ATT =~ att1 + att2 + att3 + att4 + att5
  SN =~ sn1 + sn2
  PBC =~ pbc1 + pbc2 + pbc3
  INT =~ int1 + int2 + int3
  BEH =~ b1 + b2
# Inner Model (Based on Steinmetz et al., 2011)
  INT ~ ATT + SN + PBC
  BEH ~ INT + PBC
  BEH ~ PBC:INT
"
est2 <- modsem(tpb, TPB, method = "lms", nodes = 32)
plot_surface(x = "INT", z = "PBC", y = "BEH", model = est2)
# }