% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/clustreeplot.R
\name{ClustreePlot}
\alias{ClustreePlot}
\title{Clustree Plot}
\usage{
ClustreePlot(
  data,
  prefix,
  flip = FALSE,
  split_by = NULL,
  split_by_sep = "_",
  palette = "Paired",
  palcolor = NULL,
  palreverse = FALSE,
  edge_palette = "Spectral",
  edge_palcolor = NULL,
  aspect.ratio = 1,
  legend.position = "right",
  legend.direction = "vertical",
  title = NULL,
  subtitle = NULL,
  xlab = NULL,
  ylab = NULL,
  expand = c(0.1, 0.1),
  theme = "theme_this",
  theme_args = list(),
  combine = TRUE,
  nrow = NULL,
  ncol = NULL,
  byrow = TRUE,
  seed = 8525,
  axes = NULL,
  axis_titles = axes,
  guides = NULL,
  design = NULL,
  ...
)
}
\arguments{
\item{data}{A data frame.}

\item{prefix}{A character string specifying the common prefix of the
resolution columns in \code{data}. All columns whose names start with
this prefix are selected as resolution columns. The suffix after the
prefix is parsed as a numeric resolution value. Supports \code{"_"}
and \code{"."} as separators between the prefix and the resolution
value (e.g. \code{"res_0.5"} or \code{"p.0.5"}).}

\item{flip}{A logical value. If \code{TRUE}, the tree is flipped so that
resolutions are displayed on the x-axis (left to right) and cluster
assignments are shown as row labels on the y-axis.
Default: \code{FALSE}.}

\item{split_by}{The column(s) to split data by and generate separate
clustree plots for each level. Each split level produces an independent
clustree plot via \code{\link{ClustreePlotAtomic}}.}

\item{split_by_sep}{A character string used to concatenate multiple
\code{split_by} column values when \code{split_by} specifies more than
one column. Default: \code{"_"}.}

\item{palette}{A character string specifying the palette to use.
A named list or vector can be used to specify the palettes for different \code{split_by} values.}

\item{palcolor}{A character string specifying the color to use in the palette.
A named list can be used to specify the colors for different \code{split_by} values.
If some values are missing, the values from the palette will be used (palcolor will be NULL for those values).}

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

\item{edge_palette}{A character string specifying the palette name for
the edge colour gradient. Edges are coloured by the number of
transitioning cells between clusters at adjacent resolutions, using
\code{ggraph::scale_edge_color_gradientn()}. Default: \code{"Spectral"}.}

\item{edge_palcolor}{A character vector of custom colours for the edge
colour gradient. When \code{NULL} (the default), colours are derived
from \code{edge_palette}.}

\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{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{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{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{combine}{A logical value. If \code{TRUE} (the default), the list
of per-split plots is combined into a single \code{patchwork} object.
If \code{FALSE}, returns the raw list of \code{ggplot} objects.}

\item{nrow, ncol, byrow}{Integers controlling the layout of combined plots
via \code{patchwork::wrap_plots()}. \code{byrow = TRUE} (default)
fills the layout row-wise. Ignored when \code{design} is provided.}

\item{seed}{The random seed for reproducibility. Passed to
\code{validate_common_args()}. Default: \code{8525}.}

\item{axes, axis_titles}{Strings controlling how axes and axis titles are
handled across combined plots. Passed to \code{\link{combine_plots}()}.
See \code{?patchwork::wrap_plots} for options (\code{"keep"},
\code{"collect"}, \code{"collect_x"}, \code{"collect_y"}).}

\item{guides}{A string controlling guide collection across combined
plots. Passed to \code{\link{combine_plots}()}.}

\item{design}{A custom layout specification for combined plots. Passed
to \code{\link{combine_plots}()}. When specified, \code{nrow},
\code{ncol}, and \code{byrow} are ignored.}

\item{...}{Additional arguments passed to \code{clustree::clustree()}.
Commonly used overrides include \code{node_size_range},
\code{node_text_size}, \code{layout} (default: \code{"sugiyama"}),
\code{show_axis}, and \code{node_text_colour}. Note that \code{x}
(the data) and \code{prefix} are set internally and cannot be
overridden here.}
}
\value{
A \code{ggplot} object (single plot), a \code{patchwork} object
(when \code{combine = TRUE} with \code{split_by}), or a \code{list} of
\code{ggplot} objects (when \code{combine = FALSE}).
}
\description{
Creates a clustree (clustering tree) plot visualising how cluster
assignments change across increasing clustering resolutions. The plot
helps identify stable clustering solutions and understand the hierarchical
relationships among clusters at different resolution thresholds.

The function expects a data frame with columns named by a common
\code{prefix} followed by numeric resolution values (e.g.
\code{"res_0.1"}, \code{"res_0.3"}, \code{"res_0.5"}). Each column
contains cluster labels (factor or character) for every observation at
that resolution.

Internally, the function uses \code{clustree::clustree()} to compute a
\code{ggraph}-based tree layout where nodes are clusters and edges
represent cells transitioning between clusters at adjacent resolutions.
Edge colour and width encode the number of transitioning cells.

Key features:
\itemize{
\item \strong{Resolution-level node colouring} — each resolution
receives a distinct colour from the selected \code{palette}.
\item \strong{Edge gradient} — edges are coloured by transition count
using a separate \code{edge_palette} colour gradient.
\item \strong{Flip support} — \code{flip = TRUE} places resolutions
on the x-axis for left-to-right reading.
\item \strong{Split by groups} — \code{split_by} generates per-group
clustree plots that are combined via \code{patchwork}.
\item \strong{Automatic dimensions} — plot height and width are
automatically computed based on the number of resolutions, clusters,
and the legend configuration.
}
}
\section{split_by Workflow (ClustreePlot)}{


When \code{split_by} is provided, the following pipeline executes:
\enumerate{
\item \strong{Argument validation} — \code{validate_common_args()}
checks the \code{seed} value and sets the random seed.
\item \strong{Theme resolution} — \code{process_theme()} resolves the
\code{theme} string or function to a theme function.
\item \strong{Split column validation} — \code{check_columns()}
resolves \code{split_by} with \code{force_factor = TRUE,
  allow_multi = TRUE, concat_multi = TRUE}.
\item \strong{Data splitting} — splits \code{data} by \code{split_by}
levels (unused levels dropped), preserving factor level order.
\item \strong{Per-split palette / colour / legend} —
\code{check_palette()}, \code{check_palcolor()}, and
\code{check_legend()} resolve per-split overrides for
\code{palette}, \code{palcolor}, \code{legend.position}, and
\code{legend.direction}.
\item \strong{Per-split title} — when \code{title} is a function, it
receives the default title (the split level name) and can return a
custom string; otherwise \code{title \%||\% split_level} is used.
\item \strong{Dispatch} — each split subset is passed to
\code{\link{ClustreePlotAtomic}} with the per-split parameters.
\item \strong{Combination} — \code{\link{combine_plots}()} assembles
the list of plots via \code{patchwork::wrap_plots}, honouring
\code{nrow}/\code{ncol}/\code{byrow}/\code{design}.
\item \strong{Combined data} — when \code{combine = TRUE}, the
combined plot's \code{data} (\code{p$data}) exposes the node layout
of every split, each row tagged with the \code{split_by} level, plus
a combined graph of all splits' nodes and links (\code{"graph"}
attribute) and the original links (\code{"edges"} attribute).
}
}

\examples{
\donttest{
set.seed(8525)
N <- 100
data <- data.frame(
    p.0.4 = sample(LETTERS[1:5], N, replace = TRUE),
    p.0.5 = sample(LETTERS[1:6], N, replace = TRUE),
    p.0.6 = sample(LETTERS[1:7], N, replace = TRUE),
    p.0.7 = sample(LETTERS[1:8], N, replace = TRUE),
    p.0.8 = sample(LETTERS[1:9], N, replace = TRUE),
    p.0.9 = sample(LETTERS[1:10], N, replace = TRUE),
    p.1 = sample(LETTERS[1:30], N, replace = TRUE),
    split = sample(1:2, N, replace = TRUE)
)

# --- Basic clustree plot ---
ClustreePlot(data, prefix = "p")

# --- Flipped layout (resolutions on x-axis) ---
ClustreePlot(data, prefix = "p", flip = TRUE)

# --- Split by group ---
ClustreePlot(data, prefix = "p", split_by = "split")

# --- Split by group with per-split palettes ---
ClustreePlot(data, prefix = "p", split_by = "split",
             palette = c("1" = "Set1", "2" = "Paired"))
}
}
