% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/UserFacingCoreFunctions.R
\name{direct_labels_plus}
\alias{direct_labels_plus}
\title{Add direct labels to grouped point or line plots}
\usage{
direct_labels_plus(
  data,
  x,
  y,
  group,
  placement = "top",
  geometry = "point",
  adj_fact = 0,
  key_labels = NULL,
  facet_vars = NULL,
  ...
)
}
\arguments{
\item{data}{A data frame containing the variables to be both plotted and
labelled. Most often, this will be the same data frame as supplied to
\code{\link[ggplot2:ggplot]{ggplot2::ggplot()}} but needn't be.}

\item{x, y}{Unquoted column names giving the x- and y-coordinates of the data
to be plotted and thus also labelled.}

\item{group}{Unquoted column name giving the grouping variable with which to
label the underlying data. Must be a single unquoted column name and not an
expression.}

\item{placement}{Where labels should be placed relative to each group.
One of "top", "right", "bottom", or "left". For geometry = "point", this
controls the target location used to choose a representative point from each
group. For geometry = "line", this chooses the endpoint or extreme point to
label. Experimenting with different placements to find the one that works
best for a particular graph is advised!}

\item{geometry}{The kind of geometry being labelled. Currently supports
"point" and "line".}

\item{adj_fact}{A single numeric value controlling how far label targets are
adjusted toward or away from the selected edge of each group. Values are
interpreted as a proportion of the group-specific x- or y-range. Positive
values move targets outward (towards the plot edge); negative values move
them inward. For geometry = "point", this changes the target spot used to
choose a particular point from each group to label, but does not move the
final label anchor away from the selected point. In practice, this is likely
not particularly useful for point geometries most of the time as a result.}

\item{key_labels}{Optional replacement contents for the labels. May be one
of:
\itemize{
\item NULL, in which case group values are used as labels (the default
behavior);
\item A labelling function;
\item a named character vector of the form
c("old_group_name" = "New label"); or
\item an unnamed character vector with one label per group. Unnamed
labels will be assigned to groups in alphanumeric order.
}}

\item{facet_vars}{Optional character vector of max length 2 (or else NULL)
giving one or two faceting variables you're using to facet your plot. When
supplied, label locations are calculated separately within each
group-by-facet combination. This is useful when adding direct labels to
faceted plots.}

\item{...}{Additional arguments passed along to
\code{\link[ggrepel:geom_text_repel]{ggrepel::geom_label_repel()}}.}
}
\value{
A ggplot2 layer produced by \code{\link[ggrepel:geom_text_repel]{ggrepel::geom_label_repel()}}.
}
\description{
\code{\link[=direct_labels_plus]{direct_labels_plus()}} adds procedurally placed text labels to grouped
point or line plots as an alternative to using a legend, which might be
space-inefficient, off to one side away from where readers will see it,
or force readers to jump their focus long distances to align groups with
labels. The function is intended as a friendlier alternative to
manually placing group labels via \code{\link[ggplot2:annotate]{ggplot2::annotate()}}. Labels are drawn
using \code{\link[ggrepel:geom_text_repel]{ggrepel::geom_label_repel()}}, so they'll repel one another as well
as the plotted data they're labeling (within reason).
}
\details{
This function is experimental. It currently works best for ordinary
scatterplots and grouped line/path plots where each group has a visually
meaningful position in two-dimensional (x/y) space. It will not
work for every ggplot2 geometry, statistic, coordinate system, or faceting
arrangement.

For point geometries, direct_labels_plus() calculates one label location
per group by finding the observed point closest to a group-specific target
positioned towards one of the "edges" of a group's cluster of points.
For "top" and "bottom" placement, the target is horizontally centered on
the group's median x-value and vertically placed near the group's maximum or
minimum y-value. For "left" and "right" placement, the same logic is
applied with x and y reversed.

For line geometries, labels are placed at the group-specific endpoint or
extreme value implied by placement: the largest x-value for "right", the
smallest x-value for "left", the largest y-value for "top", and the
smallest y-value for "bottom". The final label anchor may then be adjusted
by adj_fact.

To help labels repel from plotted points or lines, the function silently adds
empty-label rows at the original data coordinates. ggrepel does not draw
these empty labels, but still uses their positions when placing visible
labels. This helps to ensure, in general, that labels neither cover each other
nor the underlying data they're labelling.

Currently, the function sets defaults for the following parameters of
\code{\link[ggrepel:geom_text_repel]{ggrepel::geom_label_repel()}}: size (5), box.padding (0.5), max.overlaps
(Inf), segment.size (1), and min.segment.length (0). However, these are
overridable, if the user provides named arguments that at least partially
match.

Known limitations:
\itemize{
\item Label locations are calculated in the raw data space supplied to the
function. Transformed scales, reversed axes, and non-Cartesian coordinate
systems may give unexpected results. Pre-transform data rather than entering
raw data and transforming later.
\item coord_flip(), coord_polar(), map projections, and other coordinate
transformations are not currently supported.
\item The function places labels according to the data values supplied in
\code{data}, not those subsequently generated by ggplot2 stat functions. For
example, to label fitted smooth lines like those from
\code{\link[ggplot2:geom_smooth]{ggplot2::geom_smooth()}}, feed this function fitted values outputted from
such a function instead of the raw data.
\item Very dense plots or plots with many groups will likely still have
overlapping or poorly placed labels. ggrepel helps, but it cannot make a
crowded plot uncrowded. Alas.
\item Polygon, ribbon, area, segment, curve, and spatial geometries are not
currently supported but might be in the future.
}
}
\examples{
ggplot2::ggplot(iris, ggplot2::aes(Sepal.Length, Sepal.Width, color = Species)) +
ggplot2::geom_point() +
direct_labels_plus(
data = iris,
x = Sepal.Length,
y = Sepal.Width,
group = Species,
placement = "right",
geometry = "point"
) +
ggplot2::guides(color = "none")

line_data = ChickWeight |>
dplyr::group_by(Diet, Time) |>
dplyr::summarize(weight = mean(weight), .groups = "drop")

ggplot2::ggplot(line_data, ggplot2::aes(Time, weight, color = Diet)) +
ggplot2::geom_line(ggplot2::aes(group = Diet)) +
direct_labels_plus(
data = line_data,
x = Time,
y = weight,
group = Diet,
placement = "right",
geometry = "line",
adj_fact = 0.05
) +
ggplot2::guides(color = "none")

}
