From 820e4ce21d8a9a81775c636af7b76a9fb3364db0 Mon Sep 17 00:00:00 2001 From: sean-connelly-cmap <156253293+sean-connelly-cmap@users.noreply.github.com> Date: Wed, 7 Aug 2024 15:28:51 -0500 Subject: [PATCH] test build with repel text --- DESCRIPTION | 2 +- NAMESPACE | 5 + man/cmapplot.Rd | 3 +- man/customproto.Rd | 13 ++- man/geom_text_lastonly.Rd | 16 +++- man/geom_text_lastonly_new.Rd | 166 ++++++++++++++++++++++++++++++++++ man/position_nudge_repel.Rd | 69 ++++++++++++++ 7 files changed, 267 insertions(+), 7 deletions(-) create mode 100644 man/geom_text_lastonly_new.Rd create mode 100644 man/position_nudge_repel.Rd diff --git a/DESCRIPTION b/DESCRIPTION index 6ac84612..66a632c0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -61,5 +61,5 @@ Suggests: rmarkdown, testthat, tidyverse -RoxygenNote: 7.2.3 +RoxygenNote: 7.3.2 VignetteBuilder: knitr diff --git a/NAMESPACE b/NAMESPACE index f63038a2..c2e61d80 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,10 +1,13 @@ # Generated by roxygen2: do not edit by hand +S3method(makeContent,textlastrepel) export(.lwd) export(GeomPointLast) export(GeomRecessions) export(GeomRecessionsText) export(GeomTextLast) +export(GeomTextLastNew) +export(PositionNudgeRepel) export(abbr_years) export(apply_cmap_default_aes) export(cmap_color_continuous) @@ -23,9 +26,11 @@ export(fetch_pal) export(finalize_plot) export(geom_recessions) export(geom_text_lastonly) +export(geom_text_lastonly_new) export(get_cmapplot_global) export(get_cmapplot_globals) export(gg_lwd_convert) +export(position_nudge_repel) export(set_cmapplot_global) export(theme_cmap) export(unapply_cmap_default_aes) diff --git a/man/cmapplot.Rd b/man/cmapplot.Rd index 33292448..69b79b95 100644 --- a/man/cmapplot.Rd +++ b/man/cmapplot.Rd @@ -2,8 +2,8 @@ % Please edit documentation in R/cmapplot.R \docType{package} \name{cmapplot} -\alias{cmapplot} \alias{cmapplot-package} +\alias{cmapplot} \title{cmapplot} \description{ This package contains extra palettes, themes and geoms for \pkg{ggplot2}, @@ -35,6 +35,7 @@ Authors: \item Noel Peterson (\href{https://orcid.org/0000-0003-1290-2362}{ORCID}) \item Greta Ritzenthaler \email{gritzenthaler@cmap.illinois.gov} \item Matthew Stern (\href{https://orcid.org/0000-0001-9119-2121}{ORCID}) + \item Sean Connelly \email{sconnelly@cmap.illinois.gov} } Other contributors: diff --git a/man/customproto.Rd b/man/customproto.Rd index 9996ce27..31424593 100644 --- a/man/customproto.Rd +++ b/man/customproto.Rd @@ -1,5 +1,6 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/geom_recessions.R, R/geom_text_lastonly.R +% Please edit documentation in R/geom_recessions.R, R/geom_text_lastonly.R, +% R/geom_text_lastonly_new.R \docType{data} \name{customproto} \alias{customproto} @@ -7,8 +8,14 @@ \alias{GeomRecessionsText} \alias{GeomTextLast} \alias{GeomPointLast} +\alias{GeomTextLastNew} \title{Custom ggproto classes} \description{ +The \code{cmapplot} package contains a few custom ggproto objects. For the +most part, these are slightly tweaked versions of ggplot2's default proto +objects. For more information about these, see +\code{\link[ggplot2:ggplot2-ggproto]{ggplot2::ggplot2-ggproto}}. + The \code{cmapplot} package contains a few custom ggproto objects. For the most part, these are slightly tweaked versions of ggplot2's default proto objects. For more information about these, see @@ -24,5 +31,9 @@ objects. For more information about these, see \item \code{GeomPointLast}: Add points to plot for maximum x-value in dataset only. +\item \code{GeomTextLastNew}: Add text to plot for maximum x-value in dataset only. + +\item \code{GeomPointLast}: Add points to plot for maximum x-value in dataset only. + }} \keyword{datasets} diff --git a/man/geom_text_lastonly.Rd b/man/geom_text_lastonly.Rd index d9110110..affa0df7 100644 --- a/man/geom_text_lastonly.Rd +++ b/man/geom_text_lastonly.Rd @@ -43,10 +43,18 @@ the plot data. The return value must be a \code{data.frame}, and will be used as the layer data. A \code{function} can be created from a \code{formula} (e.g. \code{~ head(.x, 10)}).} -\item{stat}{The statistical transformation to use on the data for this -layer, either as a \code{ggproto} \code{Geom} subclass or as a string naming the -stat stripped of the \code{stat_} prefix (e.g. \code{"count"} rather than -\code{"stat_count"})} +\item{stat}{The statistical transformation to use on the data for this layer. +When using a \verb{geom_*()} function to construct a layer, the \code{stat} +argument can be used the override the default coupling between geoms and +stats. The \code{stat} argument accepts the following: +\itemize{ +\item A \code{Stat} ggproto subclass, for example \code{StatCount}. +\item A string naming the stat. To give the stat as a string, strip the +function name of the \code{stat_} prefix. For example, to use \code{stat_count()}, +give the stat as \code{"count"}. +\item For more information and other ways to specify the stat, see the +\link[ggplot2:layer_stats]{layer stat} documentation. +}} \item{position}{Position adjustment, either as a string, or the result of a call to a position adjustment function. Cannot be jointy specified with diff --git a/man/geom_text_lastonly_new.Rd b/man/geom_text_lastonly_new.Rd new file mode 100644 index 00000000..1f354a21 --- /dev/null +++ b/man/geom_text_lastonly_new.Rd @@ -0,0 +1,166 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/geom_text_lastonly_new.R +\name{geom_text_lastonly_new} +\alias{geom_text_lastonly_new} +\title{Text (Last Only) New} +\usage{ +geom_text_lastonly_new( + mapping = NULL, + data = NULL, + stat = "identity", + position = NULL, + parse = FALSE, + box.padding = 0.25, + point.padding = 1e-06, + min.segment.length = 0.5, + arrow = NULL, + force = 1, + force_pull = 1, + max.time = 0.5, + max.iter = 10000, + max.overlaps = getOption("ggrepel.max.overlaps", default = 10), + nudge_x = 0.25, + nudge_y = 0, + xlim = c(NA, NA), + ylim = c(NA, NA), + na.rm = FALSE, + check_overlap = FALSE, + direction = c("both", "y", "x"), + seed = NA, + verbose = FALSE, + show.legend = FALSE, + inherit.aes = TRUE, + add_points = FALSE, + text_aes = NULL, + point_aes = NULL, + ... +) +} +\arguments{ +\item{mapping}{Set of aesthetic mappings created by \code{\link[ggplot2]{aes}} or +\code{\link[ggplot2]{aes_}}. If specified and \code{inherit.aes = TRUE} (the +default), is combined with the default mapping at the top level of the +plot. You only need to supply \code{mapping} if there isn't a mapping +defined for the plot.} + +\item{data}{A data frame. If specified, overrides the default data frame +defined at the top level of the plot.} + +\item{stat}{The statistical transformation to use on the data for this +layer, as a string.} + +\item{position}{Position adjustment, either as a string, or the result of +a call to a position adjustment function.} + +\item{parse}{If TRUE, the labels will be parsed into expressions and +displayed as described in ?plotmath} + +\item{box.padding}{Amount of padding around bounding box, as unit or number. +Defaults to 0.25. (Default unit is lines, but other units can be specified +by passing \code{unit(x, "units")}).} + +\item{point.padding}{Amount of padding around labeled point, as unit or +number. Defaults to 0. (Default unit is lines, but other units can be +specified by passing \code{unit(x, "units")}).} + +\item{min.segment.length}{Skip drawing segments shorter than this, as unit or +number. Defaults to 0.5. (Default unit is lines, but other units can be +specified by passing \code{unit(x, "units")}).} + +\item{arrow}{specification for arrow heads, as created by \code{\link[grid]{arrow}}} + +\item{force}{Force of repulsion between overlapping text labels. Defaults +to 1.} + +\item{force_pull}{Force of attraction between a text label and its +corresponding data point. Defaults to 1.} + +\item{max.time}{Maximum number of seconds to try to resolve overlaps. +Defaults to 0.5.} + +\item{max.iter}{Maximum number of iterations to try to resolve overlaps. +Defaults to 10000.} + +\item{max.overlaps}{Exclude text labels when they overlap too many other +things. For each text label, we count how many other text labels or other +data points it overlaps, and exclude the text label if it has too many overlaps. +Defaults to 10.} + +\item{nudge_x, nudge_y}{Horizontal and vertical adjustments to nudge the +starting position of each text label. The units for \code{nudge_x} and +\code{nudge_y} are the same as for the data units on the x-axis and y-axis.} + +\item{xlim, ylim}{Limits for the x and y axes. Text labels will be constrained +to these limits. By default, text labels are constrained to the entire plot +area.} + +\item{na.rm}{If \code{FALSE} (the default), removes missing values with +a warning. If \code{TRUE} silently removes missing values.} + +\item{direction}{"both", "x", or "y" -- direction in which to adjust position of labels} + +\item{seed}{Random seed passed to \code{\link[base]{set.seed}}. Defaults to +\code{NA}, which means that \code{set.seed} will not be called.} + +\item{verbose}{If \code{TRUE}, some diagnostics of the repel algorithm are printed} + +\item{show.legend}{logical. Should this layer be included in the legends? +\code{NA}, the default, includes if any aesthetics are mapped. +\code{FALSE} never includes, and \code{TRUE} always includes.} + +\item{inherit.aes}{If \code{FALSE}, overrides the default aesthetics, +rather than combining with them. This is most useful for helper functions +that define both data and aesthetics and shouldn't inherit behaviour from +the default plot specification, e.g. \code{\link[ggplot2]{borders}}.} + +\item{add_points}{If \code{TRUE}, points will be added to the plot (for the +labeled data only). Default size=2, color will match line color.} + +\item{text_aes, point_aes}{Named list, additional aesthetics to send to the +text and point geoms, respectively.} + +\item{...}{Additional aesthetics to send to BOTH the point and text geoms. +Note that if \code{add_points = FALSE}, additional parameters can be passed +to the text geom here, rather than in \code{text_aes}, without breaking.} +} +\description{ +Label only the last point(s) on a plot. \code{geom_text_lastonly_new()} can be +used instead of \code{ggplot2::geom_text()} when only the last point(s) +should be labeled. This is accomplished by identifying the maximum value of +\code{x} in \code{data} and applying a filter to omit records where \code{x} +is less than the maximum. +} +\details{ +Labels are placed by default to the right of the final point, and may be +partially cut off by the plot limits. There are two known ways to address +this: \enumerate{ \item Turn off panel clipping, e.g. with +\code{coord_cartesian(clip = "off")}. Substitute the correct coordinate +system for your plot--all have a \code{clip} argument available. Note that +this will allow all geoms in the plot to draw outside the panel area, which +may have unintended consequences. \item Manually expand the \code{x} scale, +e.g. with \code{scale_x_continuous(expand=expand_scale(mult=0.10))} or +\code{coord_cartesian(xlim = c(min, max))}. } + +Code was mostly copied from the source of \code{ggrepel::geom_text_repel()} and +\code{ggplot2::geom_point()}. +} +\examples{ +df <- data.frame(year=2010:2020, value=runif(22), var=c(rep("A", 11), rep("B", 11))) + +# Without points, label formatting or x-axis expansion +ggplot(df, aes(x=year, y=value, color=var)) + + geom_line() + + labs(title="Random lines") + + scale_y_continuous("Percentage of absolutely nothing") + + scale_x_continuous("Year") + + geom_text_lastonly_new() + +# With points, label formatting and x-axis expansion +ggplot(df, aes(x=year, y=value, color=var, label=sprintf("\%.1f\%\%", 100*value))) + + geom_line() + + labs(title="Random lines") + + scale_y_continuous("Percentage of absolutely nothing", labels=scales::percent) + + scale_x_continuous("Year", expand=expansion(mult=c(0.05, 0.10))) + + geom_text_lastonly_new(add_points=TRUE, text_aes=list(fontface="bold"), point_aes=list(size=2.5)) + +} diff --git a/man/position_nudge_repel.Rd b/man/position_nudge_repel.Rd new file mode 100644 index 00000000..a117dcab --- /dev/null +++ b/man/position_nudge_repel.Rd @@ -0,0 +1,69 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/position-nudge-repel.R +\name{position_nudge_repel} +\alias{position_nudge_repel} +\title{Nudge labels a fixed distance from points} +\usage{ +position_nudge_repel(x = 0, y = 0) +} +\arguments{ +\item{x, y}{Amount of horizontal and vertical distance to move. Same units +as the data on the x and y axes.} +} +\description{ +\code{position_nudge_repel} is useful for adjusting the starting +position of text labels before they are repelled from data points. +} +\examples{ + +df <- data.frame( + x = c(1,3,2,5), + y = c("a","c","d","c") +) + +ggplot(df, aes(x, y)) + + geom_point() + + geom_text_repel(aes(label = y)) + +ggplot(df, aes(x, y)) + + geom_point() + + geom_text_repel( + aes(label = y), + min.segment.length = 0, + position = position_nudge_repel(x = 0.1, y = 0.15) + ) + +# The values for x and y can be vectors +ggplot(df, aes(x, y)) + + geom_point() + + geom_text_repel( + aes(label = y), + min.segment.length = 0, + position = position_nudge_repel( + x = c(0.1, 0, -0.1, 0), + y = c(0.1, 0.2, -0.1, -0.2) + ) + ) + +# We can also use geom_text_repel() with arguments nudge_x, nudge_y +ggplot(df, aes(x, y)) + + geom_point() + + geom_text_repel( + aes(label = y), + min.segment.length = 0, + nudge_x = 0.1, + nudge_y = 0.15 + ) + +# The arguments nudge_x, nudge_y also accept vectors +ggplot(df, aes(x, y)) + + geom_point() + + geom_text_repel( + aes(label = y), + min.segment.length = 0, + nudge_x = c(0.1, 0, -0.1, 0), + nudge_y = c(0.1, 0.2, -0.1, -0.2) + ) + +} +\concept{position adjustments}