% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/plot_interaction.R
\name{plot_surface}
\alias{plot_surface}
\title{Plot Surface for Interaction Effects}
\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{
\item{x}{A character string specifying the name of the first predictor variable.}

\item{z}{A character string specifying the name of the second predictor variable.}

\item{y}{A character string specifying the name of the outcome variable.}

\item{model}{A model object of class \code{\link{modsem_pi}}, \code{\link{modsem_da}}, \code{\link{modsem_mplus}}, or \code{lavaan}. The model should
include paths for the predictors (\code{x}, \code{z}, and \code{xz}) to the outcome (\code{y}).}

\item{min_x}{Numeric. Minimum value of \code{x} in z-scores. Default is -3.}

\item{max_x}{Numeric. Maximum value of \code{x} in z-scores. Default is 3.}

\item{min_z}{Numeric. Minimum value of \code{z} in z-scores. Default is -3.}

\item{max_z}{Numeric. Maximum value of \code{z} in z-scores. Default is 3.}

\item{standardized}{Should coefficients be standardized beforehand?}

\item{detail}{Numeric. Step size for the grid of \code{x} and \code{z} values, determining the resolution of the surface.
Smaller values increase plot resolution. Default is \code{1e-2}.}

\item{xz}{Optional. A character string or vector specifying the interaction term between \code{x} and \code{z}.
If \code{NULL}, the interaction term is constructed as \code{paste(x, z, sep = ":")} and adjusted for specific model classes.}

\item{colorscale}{Character or list. Colorscale used to color the surface.
- Default is \code{"Viridis"}, which matches the classic Plotly default.
- Can be a built-in palette name (e.g., \code{"Greys"}, \code{"Plasma"}, \code{"Turbo"}),
  or a custom two-column list with numeric stops (\code{0}–\code{1}) and color codes.
Example custom scale:
\code{list(c(0, "white"), c(1, "black"))} for a black-and-white gradient.}

\item{reversescale}{Logical. If \code{TRUE}, reverses the color mapping so that
low values become high colors and vice versa.
Default is \code{FALSE}.}

\item{showscale}{Logical. If \code{TRUE}, displays the colorbar legend
alongside the plot.
Default is \code{TRUE}.}

\item{cmin}{Numeric or \code{NULL}. The minimum value for the colorscale mapping.
If \code{NULL}, the minimum of the data (\code{proj_y}) is used automatically.
Use this to standardize the color range across multiple plots.}

\item{cmax}{Numeric or \code{NULL}. The maximum value for the colorscale mapping.
If \code{NULL}, the maximum of the data (\code{proj_y}) is used automatically.
Use this to standardize the color range across multiple plots.}

\item{surface_opacity}{Numeric (0–1). Controls the opacity of the surface.
- \code{1} = fully opaque (default)
- \code{0} = fully transparent
Useful when overlaying multiple surfaces or highlighting gridlines.}

\item{grid}{Logical. If \code{TRUE}, draws gridlines (wireframe)
directly on the surface using Plotly's contour features.
Default is \code{FALSE}.}

\item{grid_nx}{Integer. Approximate number of gridlines to draw along the
**x-axis** direction when \code{grid = TRUE}.
Higher values create a denser grid.
Default is \code{12}.}

\item{grid_ny}{Integer. Approximate number of gridlines to draw along the
**y-axis** direction when \code{grid = TRUE}.
Higher values create a denser grid.
Default is \code{12}.}

\item{grid_color}{Character. Color of the gridlines drawn on the surface.
Must be a valid CSS color string, including \code{rgba()} for transparency.
- Default is \code{"rgba(0,0,0,0.45)"} (semi-transparent black).
Example: \code{"rgba(255,255,255,0.8)"} for semi-transparent white lines.}

\item{group}{Which group to create surface plot for. Only relevant for multigroup
models. Must be an integer index, representing the nth group.}

\item{...}{Additional arguments passed to \code{plotly::plot_ly}.}
}
\value{
A \code{plotly} surface plot object displaying the predicted values of \code{y} across the grid of \code{x} and \code{z} values.
  The color bar shows the values of \code{y}.
}
\description{
Generates a 3D surface plot to visualize the interaction effect of two variables (\code{x} and \code{z})
on an outcome (\code{y})
using parameter estimates from a supported model object (e.g., \code{lavaan} or \code{modsem}).
The function allows specifying ranges for \code{x} and \code{z} in standardized z-scores, which are then transformed
back to the original scale based on their means and standard deviations.
}
\details{
The input \code{min_x}, \code{max_x}, \code{min_z}, and \code{max_z} define the range of \code{x} and \code{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 \code{y} over the grid of \code{x} and \code{z}.

The function supports models of class \code{modsem} (with subclasses \code{modsem_pi}, \code{modsem_da}, \code{modsem_mplus}) and \code{lavaan}.
For \code{lavaan} models, it is not designed for multigroup models, and a warning will be issued if multiple groups are detected.
}
\note{
The interaction term (\code{xz}) may need to be manually specified for some models. For non-\code{lavaan} models,
interaction terms may have their separator (\code{:}) 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)
}

}
