% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/geom-bar-3d.R
\name{geom_bar_3d}
\alias{geom_bar_3d}
\alias{stat_bar_3d}
\title{3D bar chart with automatic counting or binning}
\usage{
geom_bar_3d(
  mapping = NULL,
  data = NULL,
  stat = StatBar3D,
  position = "identity",
  ...,
  bins = 10,
  binwidth = NULL,
  drop = TRUE,
  width = 1,
  faces = "all",
  light = NULL,
  cull_backfaces = TRUE,
  sort_method = NULL,
  scale_depth = TRUE,
  force_convex = FALSE,
  na.rm = FALSE,
  show.legend = NA,
  inherit.aes = TRUE
)

stat_bar_3d(
  mapping = NULL,
  data = NULL,
  geom = GeomPolygon3D,
  position = "identity",
  ...,
  bins = 10,
  binwidth = NULL,
  drop = TRUE,
  width = 1,
  faces = "all",
  light = NULL,
  cull_backfaces = TRUE,
  sort_method = NULL,
  scale_depth = TRUE,
  force_convex = FALSE,
  na.rm = FALSE,
  show.legend = NA,
  inherit.aes = TRUE
)
}
\arguments{
\item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}}.}

\item{data}{The data to be displayed in this layer.}

\item{stat}{The statistical transformation to use. Defaults to \code{StatBar3D}.}

\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{bins}{Number of bins in each dimension. Either a single value (used for both x and y)
or a vector of length 2 giving \code{c(bins_x, bins_y)}. Default is 10. Ignored for discrete
variables.}

\item{binwidth}{Bin width in each dimension. Either a single value or a vector of length 2
giving \code{c(binwidth_x, binwidth_y)}. If provided, overrides \code{bins}. Ignored for discrete
variables.}

\item{drop}{If \code{TRUE} (the default), empty bins/combinations are not rendered. If \code{FALSE},
empty bins render as zero-height columns.}

\item{width}{Column width as a fraction of bin spacing. Either a single value (used for both
x and y) or a vector of length 2 giving \code{c(width_x, width_y)}. Default is 1.0
(columns touch). Use values less than 1 for gaps between columns.}

\item{faces}{Character vector specifying which faces to render. Options:
\itemize{
\item \code{"all"} (default): Render all 6 faces
\item \code{"none"}: Render no faces
\item Vector of face names: \code{c("zmax", "xmin", "ymax")}, etc.
}
Valid face names: "xmin", "xmax", "ymin", "ymax", "zmin", "zmax".
Note that this setting acts jointly with backface culling, which removes faces whose
interior faces the viewer -- e.g., when \code{cull_backfaces = TRUE} and \code{faces = "all"}
(the default), only front faces are rendered.}

\item{light}{A lighting specification object created by \code{\link[=light]{light()}},\code{"none"} to disable
lighting, or \code{NULL} to inherit plot-level lighting specs from the coord. Specify
plot-level lighting in \code{coord_3d()} and layer-specific lighting in \verb{geom_*3d()}
functions.}

\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{scale_depth}{Logical indicating whether polygon linewidths should be scaled to make closer lines
wider and farther lines narrower. Default is TRUE. Scaling is based on the mean depth of a polygon.}

\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{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{
Creates 3D bar charts by automatically counting discrete data or binning continuous data.
This is the 3D analogue of \code{\link[ggplot2:geom_bar]{ggplot2::geom_bar()}} and \code{\link[ggplot2:geom_histogram]{ggplot2::geom_histogram()}}.
}
\details{
The stat automatically detects whether x and y are discrete or continuous:
\itemize{
\item \strong{Both discrete}: Counts occurrences of each (x, y) combination
\item \strong{Both continuous}: Performs 2D binning (like a 3D histogram)
\item \strong{Mixed}: Bins the continuous axis while preserving discrete groups
}

For pre-computed bar heights, use \code{\link[=geom_col_3d]{geom_col_3d()}} instead.
}
\section{Aesthetics}{

\code{stat_bar_3d()} requires the following aesthetics:
\itemize{
\item \strong{x}: X coordinate
\item \strong{y}: Y coordinate
}

And optionally understands:
\itemize{
\item \strong{weight}: Observation weights for counting
}
}

\section{Computed variables}{

These variables can be used with \code{after_stat()} to map to aesthetics:
\itemize{
\item \code{count}: Number of observations in each bin (default for z)
\item \code{proportion}: Count divided by total count (sums to 1)
\item \code{ncount}: Count scaled to maximum of 1
\item \code{density}: Count divided by (total count × bin area); integrates to 1 for continuous data
\item \code{ndensity}: Density scaled to maximum of 1
}
}

\examples{
# Discrete x and y: count combinations
d_discrete <- data.frame(
  x = sample(letters[1:4], 200, replace = TRUE),
  y = sample(LETTERS[1:3], 200, replace = TRUE)
)
ggplot(d_discrete, aes(x, y)) +
  geom_bar_3d() +
  coord_3d()

# Continuous x and y: 2D histogram
d_cont <- data.frame(x = rnorm(1000), y = rnorm(1000))
ggplot(d_cont, aes(x, y)) +
  geom_bar_3d() +
  coord_3d()

# Mixed: one discrete, one continuous
d_mixed <- data.frame(
  group = rep(c("A", "B", "C"), each = 100),
  value = c(rnorm(100, 2), rnorm(100, 1, 2), rnorm(100, 0))
)
ggplot(d_mixed, aes(x = group, y = value, fill = group)) +
  geom_bar_3d(bins = 20, width = c(.5, 1)) +
  coord_3d(scales = "fixed", ratio = c(1, 1, .1))

# Use density instead of count for z
ggplot(d_mixed,
      aes(x = group, y = value, z = after_stat(density))) +
  geom_bar_3d(bins = 20, width = c(.5, 1)) +
  coord_3d()

# Show empty bins with drop = FALSE
ggplot(d_cont, aes(x, y)) +
  geom_bar_3d(drop = FALSE) +
  coord_3d()

}
\seealso{
\code{\link[=geom_col_3d]{geom_col_3d()}} for pre-computed heights, \code{\link[=coord_3d]{coord_3d()}} for 3D coordinate systems,
\code{\link[=light]{light()}} for lighting specifications.
}
