| Title: | Publication-Quality 'ggplot2' Annotation |
| Version: | 0.1.0 |
| Description: | Annotation helper functions for publication-quality 'ggplot2' visualisation. These functions make it easier to annotate plots in a way that stays consistent with the set theme. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/davidhodge931/ggscribe, https://davidhodge931.github.io/ggscribe/ |
| BugReports: | https://github.com/davidhodge931/ggscribe/issues |
| Depends: | R (≥ 4.1.0) |
| Imports: | farver, ggplot2 (≥ 4.0.0), glue, grid, rlang, scales |
| Encoding: | UTF-8 |
| Language: | en-GB |
| RoxygenNote: | 7.3.3 |
| Suggests: | blends, dplyr, flexoki, ggrefine, ggwidth, jumble, knitr, rmarkdown, spelling, stringr |
| Config/testthat/edition: | 3 |
| NeedsCompilation: | no |
| Packaged: | 2026-04-29 10:09:30 UTC; david |
| Author: | David Hodge |
| Maintainer: | David Hodge <davidhodge931@gmail.com> |
| Repository: | CRAN |
| Date/Publication: | 2026-05-02 09:20:02 UTC |
ggscribe: Publication-Quality 'ggplot2' Annotation
Description
Annotation helper functions for publication-quality 'ggplot2' visualisation. These functions make it easier to annotate plots in a way that stays consistent with the set theme.
Author(s)
Maintainer: David Hodge davidhodge931@gmail.com (ORCID) [copyright holder]
See Also
Useful links:
Report bugs at https://github.com/davidhodge931/ggscribe/issues
A mapped aesthetic for text colour on fill
Description
Modifies a mapped colour (or fill) aesthetic for contrast against the fill (or colour) aesthetic.
Function can be spliced into ggplot2::aes with rlang::!!!.
Usage
aes_contrast(..., dark = NULL, light = NULL, aesthetic = "colour")
Arguments
... |
Require named arguments (and support trailing commas). |
dark |
A dark colour. If NULL, derived from theme text or panel background. |
light |
A light colour. If NULL, derived from theme text or panel background. |
aesthetic |
The aesthetic to be modified for contrast. Either "colour" (default) or "fill". |
Value
A ggplot2 aesthetic in ggplot2::aes.
See Also
Examples
library(ggplot2)
library(dplyr)
library(stringr)
set_theme(
ggrefine::theme_light(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
ggwidth::set_equiwidth(equiwidth = 1.75)
mtcars |>
count(cyl, am) |>
mutate(
am = if_else(am == 0, "Automatic", "Manual"),
cyl = as.factor(cyl)
) |>
ggplot(aes(x = am, y = n, colour = cyl, fill = cyl, label = n)) +
geom_col(
position = position_dodge2(preserve = "single", padding = 0.05),
width = ggwidth::get_width(n = 2, n_dodge = 3),
) +
scale_fill_discrete(palette = jumble::jumble) +
scale_colour_discrete(palette = blends::multiply(jumble::jumble)) +
geom_text(
mapping = ggscribe::aes_contrast(), # or aes(!!!ggscribe::aes_contrast()),
position = position_dodge2(
width = ggwidth::get_width(n = 2, n_dodge = 3),
padding = 0.05,
preserve = "single"),
vjust = 1.33,
show.legend = FALSE,
) +
scale_y_continuous(expand = expansion(c(0, 0.05))) +
ggrefine::modern(x_type = "discrete")
mtcars |>
count(cyl, am) |>
mutate(
am = if_else(am == 0, "automatic", "manual"),
am = stringr::str_to_sentence(am),
cyl = as.factor(cyl)
) |>
ggplot(aes(y = am, x = n, colour = cyl, fill = cyl, label = n)) +
geom_col(
position = position_dodge2(preserve = "single", padding = 0.05),
width = ggwidth::get_width(n = 2, n_dodge = 3, orientation = "y"),
) +
scale_fill_discrete(palette = jumble::jumble) +
scale_colour_discrete(palette = blends::multiply(jumble::jumble)) +
geom_text(
mapping = ggscribe::aes_contrast(), # or aes(!!!ggscribe::aes_contrast()),
position = position_dodge2(
width = ggwidth::get_width(n = 2, n_dodge = 3, orientation = "y"),
preserve = "single",
padding = 0.05,
),
hjust = 1.25,
show.legend = FALSE,
) +
scale_x_continuous(expand = expansion(c(0, 0.05))) +
ggrefine::modern(y_type = "discrete")
Annotate an axis bracket
Description
Draws a bracket spanning min(breaks) to max(breaks) along an axis edge
or at a floating data position. The bar uses the same rendering path as
axis_line(); the caps use the same path as axis_ticks().
Requires coord_cartesian(clip = "off").
Usage
axis_bracket(
...,
position = NULL,
xintercept = NULL,
yintercept = NULL,
breaks,
colour = NULL,
linewidth = NULL,
linetype = NULL,
length = ggplot2::rel(1)
)
Arguments
... |
Not used. Forces named arguments. |
position |
One of |
xintercept |
For |
yintercept |
For |
breaks |
A numeric vector of length >= 2. The bar spans |
colour |
Inherits from |
linewidth |
Inherits from |
linetype |
Inherits from |
length |
Length of the bracket caps as a grid unit. Supports
|
Value
A list of ggplot2 annotation layers.
See Also
axis_line(), axis_ticks(),
axis_text(), reference_line(),
panel_shade(), sec_axis_text()
Examples
library(ggplot2)
library(dplyr)
set_theme(
ggrefine::theme_grey(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
mtcars |>
ggplot(aes(x = wt, y = mpg, colour = as.factor(gear), fill = as.factor(gear))) +
scale_colour_discrete(palette = blends::multiply(get_theme()$palette.colour.discrete)) +
#clip = "off" is required for axis_text, axis_ticks and axis_bracket
coord_cartesian(clip = "off") +
#reference lines and shade
ggscribe::reference_line(xintercept = 2.4) +
ggscribe::reference_line(yintercept = 12) +
ggscribe::panel_shade(
xmin = 4,
xmax = 5,
) +
#top axis
scale_x_continuous(
sec.axis = ggscribe::sec_axis_text(
breaks = c(mean(c(4, 5))),
labels = c("Range"),
guide = ggscribe::guide_sec_axis_text(
angle = 90,
)
)
) +
ggscribe::axis_bracket(
position = "top",
breaks = c(4, 5),
) +
ggscribe::axis_text(
position = "top",
breaks = c(2.4),
labels = c("Threshold"),
) +
#right axis
ggscribe::axis_text(
position = "right",
breaks = 12,
labels = "Threshold",
) +
#'geom
geom_point() +
#annotations fit plot
theme(plot.background = element_rect(colour = "grey92"))
Annotate an axis line
Description
Draws a line along an axis edge, with style defaults taken from the
axis.line element of the set theme. Requires coord_cartesian(clip = "off").
Usage
axis_line(
...,
position = NULL,
xintercept = NULL,
yintercept = NULL,
colour = NULL,
linewidth = NULL,
linetype = NULL
)
Arguments
... |
Not used. Forces named arguments. |
position |
One of |
xintercept |
For |
yintercept |
For |
colour |
Inherits from |
linewidth |
Inherits from |
linetype |
Inherits from |
Value
A list of ggplot2 annotation layers.
See Also
axis_ticks(), axis_text(),
axis_bracket(), reference_line(),
panel_shade(), sec_axis_text()
Annotate axis text
Description
Draws text labels at specified break positions along an axis, with style
defaults taken from the axis.text element of the set theme. Requires
coord_cartesian(clip = "off").
Usage
axis_text(
...,
position = NULL,
xintercept = NULL,
yintercept = NULL,
breaks,
labels = NULL,
colour = NULL,
size = NULL,
family = NULL,
hjust = NULL,
vjust = NULL,
angle = 0,
length = ggplot2::rel(1)
)
Arguments
... |
Not used. Forces named arguments. |
position |
One of |
xintercept |
For |
yintercept |
For |
breaks |
A numeric vector of break positions. |
labels |
One of:
|
colour |
Inherits from |
size |
Inherits from |
family |
Inherits from |
hjust, vjust |
Justification. Auto-calculated from |
angle |
Text rotation angle. Defaults to |
length |
Offset from the axis edge including tick length and margin.
Supports |
Value
A list of ggplot2 annotation layers.
See Also
axis_line(), axis_ticks(),
axis_bracket(), reference_line(),
panel_shade(), sec_axis_text()
Examples
library(ggplot2)
library(dplyr)
set_theme(
ggrefine::theme_grey(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
mtcars |>
ggplot(aes(x = wt, y = mpg, colour = as.factor(gear), fill = as.factor(gear))) +
scale_colour_discrete(palette = blends::multiply(get_theme()$palette.colour.discrete)) +
#clip = "off" is required for axis_text, axis_ticks and axis_bracket
coord_cartesian(clip = "off") +
#reference lines and shade
ggscribe::reference_line(xintercept = 2.4) +
ggscribe::reference_line(yintercept = 12) +
ggscribe::panel_shade(
xmin = 4,
xmax = 5,
) +
#top axis
scale_x_continuous(
sec.axis = ggscribe::sec_axis_text(
breaks = c(mean(c(4, 5))),
labels = c("Range"),
guide = ggscribe::guide_sec_axis_text(
angle = 90,
)
)
) +
ggscribe::axis_bracket(
position = "top",
breaks = c(4, 5),
) +
ggscribe::axis_text(
position = "top",
breaks = c(2.4),
labels = c("Threshold"),
) +
#right axis
ggscribe::axis_text(
position = "right",
breaks = 12,
labels = "Threshold",
) +
#'geom
geom_point() +
#annotations fit plot
theme(plot.background = element_rect(colour = "grey92"))
Annotate axis ticks
Description
Draws axis ticks at specified break positions, with style defaults taken from
the axis.ticks element of the set theme. Requires
coord_cartesian(clip = "off").
Usage
axis_ticks(
...,
position = NULL,
xintercept = NULL,
yintercept = NULL,
breaks,
minor = FALSE,
colour = NULL,
linewidth = NULL,
length = ggplot2::rel(1)
)
Arguments
... |
Not used. Forces named arguments. |
position |
One of |
xintercept |
For |
yintercept |
For |
breaks |
A numeric vector of break positions. |
minor |
Logical. If |
colour |
Inherits from |
linewidth |
Inherits from |
length |
Total tick length as a grid unit. Supports |
Value
A list of ggplot2 annotation layers.
See Also
axis_line(), axis_text(),
axis_bracket(), reference_line(),
panel_shade(), sec_axis_text()
Guide optimised for secondary axis text annotations
Description
A wrapper around ggplot2::guide_axis() that defaults to using
theme_sec_axis_text(). This guide is designed to strip away standard axis
furniture (like lines and ticks) while preserving text, making it ideal for
secondary axes used as margin labels.
Usage
guide_sec_axis_text(..., theme = theme_sec_axis_text())
Arguments
... |
Additional arguments passed to |
theme |
A |
Value
A guide object to be used in a scale's guide argument or within
sec_axis_text().
See Also
sec_axis_text(), theme_sec_axis_text()
Examples
library(ggplot2)
library(dplyr)
set_theme(
ggrefine::theme_grey(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
mtcars |>
ggplot(aes(x = wt, y = mpg, colour = as.factor(gear), fill = as.factor(gear))) +
scale_colour_discrete(palette = blends::multiply(get_theme()$palette.colour.discrete)) +
#clip = "off" is required for axis_text, axis_ticks and axis_bracket
coord_cartesian(clip = "off") +
#reference lines and shade
ggscribe::reference_line(xintercept = 2.4) +
ggscribe::reference_line(yintercept = 12) +
ggscribe::panel_shade(
xmin = 4,
xmax = 5,
) +
#top axis
scale_x_continuous(
sec.axis = ggscribe::sec_axis_text(
breaks = c(mean(c(4, 5))),
labels = c("Range"),
guide = ggscribe::guide_sec_axis_text(
angle = 90,
)
)
) +
ggscribe::axis_bracket(
position = "top",
breaks = c(4, 5),
) +
ggscribe::axis_text(
position = "top",
breaks = c(2.4),
labels = c("Threshold"),
) +
#right axis
ggscribe::axis_text(
position = "right",
breaks = 12,
labels = "Threshold",
) +
#'geom
geom_point() +
#annotations fit plot
theme(plot.background = element_rect(colour = "grey92"))
Annotate a shaded panel region
Description
Draws a filled rectangle over the panel with colour defaults taken from the set theme. Defaults to a subtle overlay across the full panel, with the fill automatically adapting to light or dark panel backgrounds. Should be placed before geom layers.
Usage
panel_shade(
...,
xmin = -Inf,
xmax = Inf,
ymin = -Inf,
ymax = Inf,
fill = "#878580",
alpha = 0.25,
colour = "transparent",
linewidth = NULL,
linetype = NULL
)
Arguments
... |
Not used. Allows trailing commas and named-argument style calls. |
xmin, xmax |
Left and right edges of the rectangle. Defaults to |
ymin, ymax |
Bottom and top edges of the rectangle. Defaults to |
fill |
Fill colour. Defaults to a neutral grey. |
alpha |
Opacity of the rectangle. Defaults to |
colour |
Border colour. Defaults to |
linewidth |
Inherits from |
linetype |
Border linetype. Defaults to |
Value
A list containing an annotation layer.
Examples
library(ggplot2)
library(dplyr)
set_theme(
ggrefine::theme_grey(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
mtcars |>
ggplot(aes(x = wt, y = mpg, colour = as.factor(gear), fill = as.factor(gear))) +
scale_colour_discrete(palette = blends::multiply(get_theme()$palette.colour.discrete)) +
#clip = "off" is required for axis_text, axis_ticks and axis_bracket
coord_cartesian(clip = "off") +
#reference lines and shade
ggscribe::reference_line(xintercept = 2.4) +
ggscribe::reference_line(yintercept = 12) +
ggscribe::panel_shade(
xmin = 4,
xmax = 5,
) +
#top axis
scale_x_continuous(
sec.axis = ggscribe::sec_axis_text(
breaks = c(mean(c(4, 5))),
labels = c("Range"),
guide = ggscribe::guide_sec_axis_text(
angle = 90,
)
)
) +
ggscribe::axis_bracket(
position = "top",
breaks = c(4, 5),
) +
ggscribe::axis_text(
position = "top",
breaks = c(2.4),
labels = c("Threshold"),
) +
#right axis
ggscribe::axis_text(
position = "right",
breaks = 12,
labels = "Threshold",
) +
#'geom
geom_point() +
#annotations fit plot
theme(plot.background = element_rect(colour = "grey92"))
Annotate a reference line
Description
Draws a reference line within the panel, with style defaults taken from the
axis.line element of the set theme.
Usage
reference_line(
...,
xintercept = NULL,
yintercept = NULL,
colour = NULL,
linewidth = NULL,
linetype = "dashed"
)
Arguments
... |
Not used. Forces named arguments. |
xintercept |
Draw a vertical reference line at this x position. |
yintercept |
Draw a horizontal reference line at this y position. |
colour |
Inherits from |
linewidth |
Inherits from |
linetype |
Defaults to |
Value
A list of ggplot2 annotation layers.
See Also
axis_line(), axis_ticks(),
axis_text(), axis_bracket(), panel_shade(),
sec_axis_text()
Examples
library(ggplot2)
library(dplyr)
set_theme(
ggrefine::theme_grey(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
mtcars |>
ggplot(aes(x = wt, y = mpg, colour = as.factor(gear), fill = as.factor(gear))) +
scale_colour_discrete(palette = blends::multiply(get_theme()$palette.colour.discrete)) +
#clip = "off" is required for axis_text, axis_ticks and axis_bracket
coord_cartesian(clip = "off") +
#reference lines and shade
ggscribe::reference_line(xintercept = 2.4) +
ggscribe::reference_line(yintercept = 12) +
ggscribe::panel_shade(
xmin = 4,
xmax = 5,
) +
#top axis
scale_x_continuous(
sec.axis = ggscribe::sec_axis_text(
breaks = c(mean(c(4, 5))),
labels = c("Range"),
guide = ggscribe::guide_sec_axis_text(
angle = 90,
)
)
) +
ggscribe::axis_bracket(
position = "top",
breaks = c(4, 5),
) +
ggscribe::axis_text(
position = "top",
breaks = c(2.4),
labels = c("Threshold"),
) +
#right axis
ggscribe::axis_text(
position = "right",
breaks = 12,
labels = "Threshold",
) +
#'geom
geom_point() +
#annotations fit plot
theme(plot.background = element_rect(colour = "grey92"))
Secondary axis optimised for text annotations
Description
Secondary axis optimised for text annotations
Usage
sec_axis_text(
breaks = ggplot2::waiver(),
labels = ggplot2::derive(),
name = NULL,
guide = ggplot2::guide_axis(theme = theme_sec_axis_text()),
...
)
Arguments
breaks |
One of:
|
labels |
One of:
|
name |
The name of the secondary axis. Use |
guide |
A guide object used to render the axis. Defaults to
|
... |
Additional arguments passed to |
Value
A AxisSecondary object for use in the sec.axis argument of
scale_x_continuous() or scale_y_continuous().
See Also
guide_sec_axis_text(), theme_sec_axis_text(), axis_text()
Examples
library(ggplot2)
library(dplyr)
set_theme(
ggrefine::theme_grey(
panel_heights = rep(unit(50, "mm"), 100),
panel_widths = rep(unit(75, "mm"), 100),
)
)
mtcars |>
ggplot(aes(x = wt, y = mpg, colour = as.factor(gear), fill = as.factor(gear))) +
scale_colour_discrete(palette = blends::multiply(get_theme()$palette.colour.discrete)) +
#clip = "off" is required for axis_text, axis_ticks and axis_bracket
coord_cartesian(clip = "off") +
#reference lines and shade
ggscribe::reference_line(xintercept = 2.4) +
ggscribe::reference_line(yintercept = 12) +
ggscribe::panel_shade(
xmin = 4,
xmax = 5,
) +
#top axis
scale_x_continuous(
sec.axis = ggscribe::sec_axis_text(
breaks = c(mean(c(4, 5))),
labels = c("Range"),
guide = ggscribe::guide_sec_axis_text(
angle = 90,
)
)
) +
ggscribe::axis_bracket(
position = "top",
breaks = c(4, 5),
) +
ggscribe::axis_text(
position = "top",
breaks = c(2.4),
labels = c("Threshold"),
) +
#right axis
ggscribe::axis_text(
position = "right",
breaks = 12,
labels = "Threshold",
) +
#'geom
geom_point() +
#annotations fit plot
theme(plot.background = element_rect(colour = "grey92"))
Theme adjustments optimised for secondary axis text annotations
Description
Theme adjustments optimised for secondary axis text annotations
Usage
theme_sec_axis_text(
axis = NULL,
axis_ticks_to = "transparent",
axis_line_to = "transparent",
axis_text_to = "keep",
axis_title_to = "keep"
)
Arguments
axis |
Character. "x", "y", or NULL (defaults to both). |
axis_ticks_to |
Action for ticks: "transparent", "blank", or "keep". |
axis_line_to |
Action for lines: "transparent", "blank", or "keep". |
axis_text_to |
Action for text: "transparent", "blank", or "keep". |
axis_title_to |
Action for titles: "transparent", "blank", or "keep". |
Value
A ggplot2 theme object.