% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/sankeyplot.R
\name{SankeyPlotAtomic}
\alias{SankeyPlotAtomic}
\title{Atomic Sankey / alluvial diagram (internal)}
\usage{
SankeyPlotAtomic(
  data,
  in_form = c("auto", "long", "lodes", "wide", "alluvia", "counts"),
  x,
  x_sep = "_",
  y = NULL,
  stratum = NULL,
  stratum_sep = "_",
  alluvium = NULL,
  alluvium_sep = "_",
  flow = FALSE,
  nodes_color = "grey30",
  links_fill_by = NULL,
  links_fill_by_sep = "_",
  links_name = NULL,
  links_color = "gray80",
  nodes_palette = "Paired",
  nodes_palcolor = NULL,
  palreverse = FALSE,
  nodes_alpha = 1,
  nodes_label = FALSE,
  nodes_width = 0.25,
  nodes_label_miny = 0,
  nodes_legend = c("auto", "separate", "merge", "none"),
  expand = c(0, 0, 0, 0),
  links_palette = "Paired",
  links_palcolor = NULL,
  links_alpha = 0.6,
  legend.box = "vertical",
  keep_empty = TRUE,
  x_text_angle = 0,
  aspect.ratio = 1,
  legend.position = "right",
  legend.direction = "vertical",
  flip = FALSE,
  theme = "theme_this",
  theme_args = list(),
  title = NULL,
  subtitle = NULL,
  xlab = NULL,
  ylab = NULL,
  facet_by = NULL,
  facet_scales = "fixed",
  facet_ncol = NULL,
  facet_nrow = NULL,
  facet_byrow = TRUE,
  ...
)
}
\arguments{
\item{data}{A data frame.}

\item{in_form}{A character string specifying the input data format.
One of \code{"auto"} (default), \code{"long"}, \code{"lodes"},
\code{"wide"}, \code{"alluvia"}, or \code{"counts"}.
\code{"long"} is an alias for \code{"lodes"}; \code{"wide"} is an alias for
\code{"alluvia"}.  See the \code{data} parameter of \code{\link{SankeyPlot}}
for format descriptions.}

\item{x}{A character vector of column name(s) for the x-axis categories.
Each unique value or concatenated pair represents a time point, state, or
position along the horizontal axis.  Behaviour depends on \code{in_form}:
for \code{"lodes"} at least one column is expected; for \code{"alluvia"}
and \code{"counts"} at least two columns are required.  In the latter two
cases \code{x_sep} is not used.}

\item{x_sep}{A character string to join multiple \code{x} columns when
\code{in_form} is \code{"lodes"} or auto-determined as lodes.
Default \code{"_"}.}

\item{y}{A character string specifying the numeric column for the y-axis
(frequency / value).  When \code{NULL} (default), the count of observations
per combination of \code{x}, \code{stratum}, \code{alluvium},
\code{links_fill_by}, and \code{facet_by} is computed automatically.
Ignored when \code{in_form} is \code{"counts"}.}

\item{stratum}{A character string specifying the column that defines the
node categories at each x-axis position.  Each unique value becomes a
stratum (node block) at each x position.  When \code{NULL}, defaults to
\code{links_fill_by}.  Multiple columns are concatenated with
\code{stratum_sep}.  Ignored in \code{"alluvia"} format.}

\item{stratum_sep}{A character string to join multiple \code{stratum}
columns.  Default \code{"_"}.}

\item{alluvium}{A character string specifying the column that identifies
individual flows (alluvia) across x-axis positions.  Each unique value
represents a single observational unit tracked across positions.  When
\code{NULL} in \code{"counts"} format, an auto-generated identifier is
created.  Multiple columns are concatenated with \code{alluvium_sep}.
Ignored in \code{"alluvia"} format.}

\item{alluvium_sep}{A character string to join multiple \code{alluvium}
columns.  Default \code{"_"}.}

\item{flow}{A logical value.  When \code{FALSE} (default),
\code{\link[ggalluvial]{geom_alluvium}()} is used for the links.  When
\code{TRUE}, \code{\link[ggalluvial]{geom_flow}()} is used instead, which
draws the flows with a directional gradient between x positions.}

\item{nodes_color}{A character string specifying the border colour of the
node (stratum) rectangles.  Use the special value \code{".fill"} to match
the border colour to the node fill colour.  Default \code{"grey30"}.}

\item{links_fill_by}{A character string specifying the column that
determines the fill colour of the links (alluvia / flows).  When
\code{NULL} in \code{"lodes"} format, defaults to \code{alluvium}.  In
\code{"counts"} format with the \code{"."} prefix, this parameter is
required.  Multiple columns are concatenated with
\code{links_fill_by_sep}.}

\item{links_fill_by_sep}{A character string to join multiple
\code{links_fill_by} columns.  Default \code{"_"}.}

\item{links_name}{A character string for the legend title of the link fill
scale.  When \code{NULL} (default), the \code{links_fill_by} column name
is used.}

\item{links_color}{A character string specifying the border colour of the
links (alluvia / flows).  Use the special value \code{".fill"} to match
the link border colour to the link fill colour.  Default \code{"gray80"}.}

\item{nodes_palette}{A character string specifying the colour palette for
the node (stratum) fill.  Passed to \code{\link{palette_this}()}.
Default \code{"Paired"}.}

\item{nodes_palcolor}{A character vector of custom colours for the node
fill, used as \code{palcolor} in \code{\link{palette_this}()}.  When
\code{NULL} (default), the palette colours are used directly.}

\item{palreverse}{A logical value indicating whether to reverse the palette. Default is FALSE.}

\item{nodes_alpha}{A numeric value in \eqn{[0, 1]} controlling the
transparency of the node (stratum) fill.  Default \code{1}.}

\item{nodes_label}{A logical value.  When \code{TRUE}, stratum labels are
drawn inside each node using \code{\link[ggplot2]{geom_label}()} with
\code{\link[ggalluvial]{StatStratum}}.  Default \code{FALSE}.}

\item{nodes_width}{A numeric value (typically 0–1) specifying the width of
the node (stratum) rectangles as a fraction of the x-axis spacing.
Default \code{0.25}.}

\item{nodes_label_miny}{A numeric value specifying the minimum y
(frequency) threshold for displaying node labels.  Nodes with y-values
below this threshold are not labelled.  Default \code{0}.}

\item{nodes_legend}{Controls how the node legend is displayed.  One of:
\describe{
\item{\code{"auto"} (default)}{Automatically determined:
if \code{nodes_label = TRUE}, or if \code{stratum} is identical to
\code{links_fill_by} with matching colours, the legend is hidden.
Otherwise, overlapping stratum values across x positions are checked:
any overlap produces a merged legend; no overlap produces separate
legends per x position.}
\item{\code{"merge"}}{A single merged legend for all nodes.}
\item{\code{"separate"}}{One legend per x-axis position, generated via
separate \code{\link[ggplot2]{scale_fill_manual}()} layers.}
\item{\code{"none"}}{No node legend is shown.}
}}

\item{expand}{The values to expand the x and y axes. It is like CSS padding.
When a single value is provided, it is used for both axes on both sides.
When two values are provided, the first value is used for the top/bottom side and the second value is used for the left/right side.
When three values are provided, the first value is used for the top side, the second value is used for the left/right side, and the third value is used for the bottom side.
When four values are provided, the values are used for the top, right, bottom, and left sides, respectively.
You can also use a named vector to specify the values for each side.
When the axis is discrete, the values will be applied as 'add' to the 'expansion' function.
When the axis is continuous, the values will be applied as 'mult' to the 'expansion' function.
See also \url{https://ggplot2.tidyverse.org/reference/expansion.html}}

\item{links_palette}{A character string specifying the colour palette for
the link fill.  Passed to \code{\link{palette_this}()}.
Default \code{"Paired"}.}

\item{links_palcolor}{A character vector of custom colours for the link
fill, used as \code{palcolor} in \code{\link{palette_this}()}.  When
\code{NULL} (default), the palette colours are used directly.}

\item{links_alpha}{A numeric value in \eqn{[0, 1]} controlling the
transparency of the link fill.  Default \code{0.6}.}

\item{legend.box}{A character string specifying the arrangement of legend
boxes, either \code{"vertical"} (default) or \code{"horizontal"}.}

\item{keep_empty}{One of FALSE, TRUE and "level". It can also take a named list to specify
different behavior for different columns. Without a named list, the behavior applies to the
categorical/character columns used on the plot, for example, the \code{x}, \code{group_by}, \code{fill_by}, etc.
\itemize{
\item{\code{FALSE} (default): Drop empty factor levels from the data before plotting.}
\item{\code{TRUE}: Keep empty factor levels and show them as a separate category in the plot.}
\item{\code{"level"}: Keep empty factor levels, but do not show them in the plot.
But they will be assigned colors from the palette to maintain consistency across multiple plots.
Alias: \code{levels}}
}}

\item{x_text_angle}{A numeric value specifying the angle of the x-axis text.}

\item{aspect.ratio}{A numeric value specifying the aspect ratio of the plot.}

\item{legend.position}{A character string specifying the position of the legend.
if \code{waiver()}, for single groups, the legend will be "none", otherwise "right".}

\item{legend.direction}{A character string specifying the direction of the legend.}

\item{flip}{A logical value.  When \code{TRUE},
\code{\link[ggplot2]{coord_flip}()} is applied to swap the x and y axes.
Default \code{FALSE}.}

\item{theme}{A character string or a theme class (i.e. ggplot2::theme_classic) specifying the theme to use.
Default is "theme_this".}

\item{theme_args}{A list of arguments to pass to the theme function.}

\item{title}{A character string specifying the title of the plot.
A function can be used to generate the title based on the default title.
This is useful when split_by is used and the title needs to be dynamic.}

\item{subtitle}{A character string specifying the subtitle of the plot.}

\item{xlab}{A character string specifying the x-axis label.}

\item{ylab}{A character string specifying the y-axis label.}

\item{facet_by}{A character string specifying the column name of the data frame to facet the plot.
Otherwise, the data will be split by \code{split_by} and generate multiple plots
and combine them into one using \code{patchwork::wrap_plots}}

\item{facet_scales}{Whether to scale the axes of facets. Default is "fixed"
Other options are "free", "free_x", "free_y". See \code{ggplot2::facet_wrap}}

\item{facet_ncol}{A numeric value specifying the number of columns in the facet.
When facet_by is a single column and facet_wrap is used.}

\item{facet_nrow}{A numeric value specifying the number of rows in the facet.
When facet_by is a single column and facet_wrap is used.}

\item{facet_byrow}{A logical value indicating whether to fill the plots by row. Default is TRUE.}

\item{...}{Additional arguments passed to
\code{\link[ggalluvial]{geom_alluvium}()} or
\code{\link[ggalluvial]{geom_flow}()}, depending on the \code{flow}
setting.  For \code{geom_flow} with a distinct \code{links_fill_by}
column, passing \code{stat = "alluvium"} preserves the fill variable.}
}
\value{
A \code{ggplot} object with \code{height} and \code{width}
attributes (in inches) attached.
}
\description{
Core implementation for drawing a Sankey (alluvial) diagram using
\code{\link[ggalluvial]{geom_alluvium}} (or \code{\link[ggalluvial]{geom_flow}})
and \code{\link[ggalluvial]{geom_stratum}}.  This function takes a \strong{single}
data frame (no \code{split_by} support) and returns a \code{ggplot} object
with faceting applied.

The function supports five input formats (\code{in_form}) which control how
the data columns are interpreted.  Nodes (strata) are rendered as vertical
blocks whose fill colour and alpha can be customised independently of the
links (alluvia / flows) connecting them.  Link colours can match node
colours or use a separate palette; link borders can be set to a fixed colour
or to follow the fill colour (\code{links_color = ".fill"}).

Automatic legend resolution determines whether nodes on different x-axis
positions receive a merged legend or separate legends, based on overlaps
between stratum values across positions.
}
\section{Architecture}{

\enumerate{
\item \strong{Format resolution} — \code{in_form} is matched and aliased
(\code{"long"} → \code{"lodes"}, \code{"wide"} → \code{"alluvia"}).
\item \strong{Data parsing by format} — one of five code paths executes:
\itemize{
\item \strong{Lodes / long} — \code{x}, \code{stratum}, \code{alluvium},
and \code{links_fill_by} are validated via
\code{\link{check_columns}()}.  Multi-column inputs are
concatenated with their respective separators.  When \code{y} is
\code{NULL}, counts are computed per (\code{x}, \code{stratum},
\code{alluvium}, \code{links_fill_by}, \code{facet_by}).
\item \strong{Counts} (x without \code{"."} prefix) — numeric \code{x}
columns are pivoted to long form via
\code{\link[tidyr]{pivot_longer}()}, creating the y-axis from the
cell values.  \code{alluvium} and \code{stratum} default to
\code{links_fill_by}.
\item \strong{Counts with source node} (x with \code{"."} as first
element, \code{is_flowcounts}) — same as counts but also injects
\code{links_fill_by} values as an additional first column of
nodes, visualising how flows originate from source groups.
\item \strong{Alluvia / wide} — validated via
\code{\link[ggalluvial]{is_alluvia_form}()} and converted to lodes
form via \code{\link[ggalluvial]{to_lodes_form}()}.
\code{stratum} and \code{alluvium} are ignored.
\item \strong{Auto / fallback} — when no other branch matches, the lodes
path is attempted and validated via
\code{\link[ggalluvial]{is_lodes_form}()}.
}
\item \strong{Palette assignment} — \code{\link{palette_this}()} resolves
colours for both nodes (\code{nodes_palette} / \code{nodes_palcolor})
and links (\code{links_palette} / \code{links_palcolor}).
\item \strong{Flow-counts guide logic} — when \code{is_flowcounts} is
\code{TRUE}, the links guide is suppressed if the first-column node
colours match the link colours, avoiding redundant legends.  When
the palettes are identical but colours differ (too few colours in
the palette), the first-column node colours are reused.
\item \strong{Legend auto-detection} — when \code{nodes_legend = "auto"}:
if \code{nodes_label = TRUE} or if \code{stratum} and
\code{links_fill_by} share identical values and colours, the nodes
legend is hidden.  Otherwise, overlapping stratum values across
x-axis positions are checked: any overlap triggers a merged legend;
no overlap produces separate legends per position.
\item \strong{Base ggplot} — constructed with \code{aes(x = x,
        stratum = stratum, alluvium = alluvium, y = y)}.
\item \strong{Separate node fill layers} — when \code{stratum} differs
from \code{links_fill_by} and \code{nodes_legend = "separate"}, a
\code{\link[ggplot2]{geom_col}()} +
\code{\link[ggplot2]{scale_fill_manual}()} layer pair is added per
x-axis position, each followed by
\code{\link[ggnewscale]{new_scale_fill}()} to produce independent
legends.
\item \strong{Link rendering} — \code{\link[ggalluvial]{geom_alluvium}()}
(default) or \code{\link[ggalluvial]{geom_flow}()} when
\code{flow = TRUE}.  When \code{links_color = ".fill"}, the colour
aesthetic is mapped to \code{links_fill_by} and the colour scale
guide is suppressed.  For \code{geom_flow} with a distinct
\code{stratum} and \code{links_fill_by}, \code{stat = "alluvium"}
is forced to preserve the fill variable through the flow stat
transformation.
\item \strong{Link fill scale} — \code{\link[ggplot2]{scale_fill_manual}()}
with \code{links_colors} and the resolved \code{links_guide}.
\item \strong{Node rendering} — \code{\link[ggalluvial]{geom_stratum}()}
with \code{nodes_color} (border) and \code{nodes_alpha}.  When
\code{nodes_color = ".fill"}, the colour aesthetic maps to
\code{stratum}.
\item \strong{Node fill scale} — \code{\link[ggplot2]{scale_fill_manual}()}
with \code{nodes_colors}.  The guide is \code{"none"} when
\code{nodes_legend} is \code{"none"} or \code{"separate"}
(already handled by per-position layers); otherwise \code{"legend"}.
\item \strong{Labels} — when \code{nodes_label = TRUE},
\code{\link[ggplot2]{geom_label}()} with
\code{stat = \link[ggalluvial]{StatStratum}} and
\code{min.y = nodes_label_miny}.
\item \strong{Axes, theme, labels} — \code{\link[ggplot2]{scale_x_discrete}()},
\code{\link[ggplot2]{scale_y_continuous}()}, custom theme, plot
title / subtitle, axis labels, and aesthetic adjustments (aspect
ratio, legend position / direction, grid removal, x-text angle).
\item \strong{Coordinate flip} — when \code{flip = TRUE},
\code{\link[ggplot2]{coord_flip}()} swaps the axes.
\item \strong{Dimension calculation} — \code{\link{calculate_plot_dimensions}()}
computes \code{height} and \code{width} attributes from the number
of x-axis positions, legend metrics, and flip state, scaled by
\code{aspect.ratio}.
\item \strong{Faceting} — \code{\link{facet_plot}()} wraps the result
when \code{facet_by} is provided.
}
}

\keyword{internal}
