% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/stat-density-3d.R
\name{geom_density_3d}
\alias{geom_density_3d}
\alias{stat_density_3d}
\title{3D surface from 2D density estimate}
\usage{
geom_density_3d(
  mapping = NULL,
  data = NULL,
  stat = "density_3d",
  position = "identity",
  ...,
  grid = "rectangle",
  n = 40,
  direction = "x",
  trim = TRUE,
  h = NULL,
  adjust = 1,
  pad = 0.1,
  min_ndensity = 0,
  light = NULL,
  cull_backfaces = FALSE,
  sort_method = NULL,
  force_convex = FALSE,
  scale_depth = TRUE,
  na.rm = FALSE,
  show.legend = NA,
  inherit.aes = TRUE
)

stat_density_3d(
  mapping = NULL,
  data = NULL,
  geom = "surface_3d",
  position = "identity",
  ...,
  grid = "rectangle",
  n = 40,
  direction = "x",
  trim = TRUE,
  h = NULL,
  adjust = 1,
  pad = 0.1,
  min_ndensity = 0,
  light = NULL,
  cull_backfaces = FALSE,
  sort_method = NULL,
  force_convex = FALSE,
  scale_depth = TRUE,
  na.rm = FALSE,
  show.legend = NA,
  inherit.aes = TRUE
)
}
\arguments{
\item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}}. This stat
requires \code{x} and \code{y} aesthetics. By default, \code{fill} is mapped to
\code{after_stat(density)} and \code{z} is mapped to \code{after_stat(density)}.}

\item{data}{The data to be displayed in this layer. Must contain x and y columns
with point coordinates.}

\item{stat}{The statistical transformation to use on the data. Defaults to \code{StatDensity3D}.}

\item{position}{Position adjustment, defaults to "identity". To collapse the result
onto one 2D surface, use \code{position_on_face()}.}

\item{...}{Other arguments passed on to the layer function (typically GeomPolygon3D), such as
aesthetics like \code{colour}, \code{fill}, \code{linewidth}, \code{annotate = annotate_3d(...)}, etc.}

\item{grid, n, direction, trim}{Parameters determining the geometry, resolution, and
orientation of the surface grid. See \link{grid_generation} for details.}

\item{h}{Bandwidth vector. If \code{NULL} (default), uses automatic bandwidth selection
via \code{MASS::bandwidth.nrd()}. Can be a single number (used for both dimensions)
or a vector of length 2 for different bandwidths in x and y directions.}

\item{adjust}{Multiplicative bandwidth adjustment factor. Values greater than 1
produce smoother surfaces; values less than 1 produce more detailed surfaces.
Default is 1.}

\item{pad}{Proportional range expansion factor. The computed density grid extends
this proportion of the raw data range beyond each data limit. Default is 0.1.}

\item{min_ndensity}{Lower cutoff for normalized density (computed variable \code{ndensity}
described below), below which to filter out results. This is particularly useful for
removing low-density corners of rectangular density grids when density surfaces are
shown for multiple groups, as in the example below. Default is 0 (no filtering).}

\item{light}{A lighting specification object created by \code{\link[=light]{light()}}, \code{light("none")}
or the string \code{"none"} to disable lighting, or \code{NULL} to inherit plot-level
lighting. Set plot-level lighting by adding \code{\link[=light]{light()}} to the plot, and
layer-specific lighting via the \code{light} argument of \verb{geom_*_3d()} functions,
which takes precedence.}

\item{cull_backfaces}{Logical indicating whether to remove back-facing polygons
from rendering. This is primarily for performance optimization but may be useful
for aesthetic reasons in some situations. Backfaces are determined using
screen-space winding order after 3D transformation. Defaults vary by geometry
type: FALSE for open surface-type geometries, TRUE for solid objects (hulls,
voxels, etc. where backfaces are generally hidden unless frontfaces are transparent
or explicitly disabled).}

\item{sort_method}{Depth sorting algorithm. See \link{sorting_methods} for details.}

\item{force_convex}{Logical indicating whether to remove polygon vertices that are not part of the
convex hull. Default value varies by geom. Specifying TRUE can help reduce artifacts in surfaces
that have polygon tiles that wrap over a visible horizon. For prism-type geoms like columns and
voxels, FALSE is safe because polygons fill always be convex.}

\item{scale_depth}{Controls whether polygon linewidths are scaled to make closer lines
wider and farther lines narrower, based on the mean depth of a polygon. \code{TRUE}
(the default) applies full scaling and \code{FALSE} disables it; a number sets the
strength directly, where \code{1} matches \code{TRUE}, \code{0} matches \code{FALSE}, values below
1 subdue the effect and values above 1 exaggerate it. This affects the layer
only; use \code{coord_3d(scale_depth = )} for gridlines, cube borders, axis ticks,
and axis text.}

\item{na.rm}{If \code{FALSE}, missing values are removed.}

\item{show.legend}{Logical indicating whether this layer should be included in legends.}

\item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics.}

\item{geom}{The geometric object used to display the data. Defaults to \code{GeomPolygon3D}.}
}
\value{
A \code{Layer} object that can be added to a ggplot.
}
\description{
A 3D version of \code{ggplot2::stat_density_2d()}.
Creates surfaces from 2D point data using kernel density estimation.
The density values become the z-coordinates of the surface, allowing
visualization of data concentration as peaks and valleys in 3D space.
}
\section{Aesthetics}{

\code{stat_density_3d()} requires the following aesthetics from input data:
\itemize{
\item \strong{x}: X coordinate of data points
\item \strong{y}: Y coordinate of data points
}

And optionally understands:
\itemize{
\item \strong{group}: Grouping variable for computing separate density surfaces
\item Additional aesthetics are passed through for surface styling
}
}

\section{Computed variables specific to StatDensity3D}{

\itemize{
\item \code{density}: The kernel density estimate at each grid point
\item \code{ndensity}: Density estimate scaled to maximum of 1 within each group
\item \code{count}: Density estimate × number of observations in group (expected count)
\item \code{n}: Number of observations in each group
}
}

\section{Grouping}{

When aesthetics like \code{colour} or \code{fill} are mapped to categorical variables,
\code{stat_density_3d()} computes separate density surfaces for each group, just
like \code{stat_density_2d()}. Each group gets its own density calculation with
proper \code{count} and \code{n} values.
}

\section{Computed variables}{

The following computed variables are available via \code{after_stat()}:
\itemize{
\item \code{x}, \code{y}, \code{z}: Grid coordinates and function values
\item \code{normal_x}, \code{normal_y}, \code{normal_z}: Surface normal components
\item \code{slope}: Gradient magnitude from surface calculations
\item \code{aspect}: Direction of steepest slope from surface calculations
\item \code{dzdx}, \code{dzdy}: Partial derivatives from surface calculation
}
}

\examples{
# Basic density surface from scattered points
p <- ggplot(faithful, aes(eruptions, waiting)) +
  coord_3d() +
  scale_fill_viridis_c()
p + geom_density_3d() + guides(fill = guide_colorbar_3d())

\donttest{

# Specify alternative grid geometry and light model
p + geom_density_3d(grid = "equilateral", n = 30, direction = "y",
                    light = light("direct"),
                    color = "white", linewidth = .1) +
  guides(fill = guide_colorbar_3d())

# Color by alternative density metric
p + geom_density_3d(aes(fill = after_stat(count)))

# Adjust bandwidth for smoother or more detailed surfaces
p + geom_density_3d(adjust = 0.5, n = 100, color = "white")  # More detail
p + geom_density_3d(adjust = 2, color = "white")   # Smoother

# As contour plot instead of default surface plot
p + stat_density_3d(geom = "contour_3d", light = "none",
                    color = "black", bins = 25,
                    sort_method = "pairwise")

# Multiple density surfaces by group,
# using normalized density to equalize peak heights
ggplot(iris, aes(Petal.Length, Sepal.Length, fill = Species)) +
  geom_density_3d(aes(z = after_stat(ndensity), group = Species),
                  color = "black", alpha = .7, light = NULL) +
  coord_3d()

# Same, but with extra padding to remove edge effects and
# with density filtering to remove rectangular artifacts
ggplot(iris, aes(Petal.Length, Sepal.Length, fill = Species)) +
  geom_density_3d(aes(z = after_stat(ndensity)),
                  pad = .3, min_ndensity = .001,
                  color = "black", alpha = .7, light = NULL) +
  coord_3d(ratio = c(3, 3, 1))

}

}
\seealso{
\code{\link[ggplot2:stat_density_2d]{ggplot2::stat_density_2d()}} for 2D density contours, \code{\link[=stat_surface_3d]{stat_surface_3d()}} for
surfaces from existing grid data, \code{\link[=light]{light()}} for lighting specifications,
\code{\link[=coord_3d]{coord_3d()}} for 3D coordinate systems.
}
