ggtibbleFrom time to time, having a list of ggplots and being able to work on them like a regular ggplot can be very helpful. For example, when writing a report, you may want to make a set of figures to separate out various levels of a group, then make separate figures for each group.
The ggtibble package has two main functions to create
sets of figures, ggtibble() and gglist().
These create a tibble with optional labels per figure and captions (for
ggtibble()) or a simpler list of figures (for
gglist()).
Both ggtibble and gglist objects can have
ggplot geoms, facets, labels, and lists of those added to them as though
they were normal ggplot objects. And, you can add a gglist
to either a ggtibble or a gglist.
Typical use will load required libraries, setup your plot data,
generate the plot, and then knit_print() it.
When generating the plot:
aes()
mapping as for any ggplot2 object,outercols which are columns outside your
dataset; one plot will be generated for each unique level of your data
with the outercols. Note that you cannot use
outercols columns within the plot, but you will use them
for captions and labels.caption with a
glue::glue_data() specification where valid columns are any
column names that are in your outercols specification. (If
you don’t give a caption, then it will be an empty string,
"".)glue::glue_data() and then passed to
labs().ggtibble, use it like a normal ggplot object adding geoms,
etc.# Note, add `fig.cap=all_plots$caption` to show the generated caption for the
# figures
library(ggtibble)
library(dplyr)
#>
#> Attaching package: 'dplyr'
#> The following objects are masked from 'package:stats':
#>
#> filter, lag
#> The following objects are masked from 'package:base':
#>
#> intersect, setdiff, setequal, union
library(ggplot2)
#>
#> Attaching package: 'ggplot2'
#> The following objects are masked from 'package:ggtibble':
#>
#> %+%, ggsave
d_plot <-
mtcars |>
mutate(
dispu = "cu. in."
)
all_plots <-
ggtibble(
d_plot,
aes(x = disp, y = hp),
outercols = c("cyl", "dispu"),
caption = "Horsepower by displacement for {cyl} cars",
labs = list(x = "Displacement ({dispu})", y = "Gross horsepower")
) +
geom_point() +
geom_line()
# The result is a tibble with columns for the `data_plot`, `figure`, and
# `caption`
as_tibble(all_plots)
#> # A tibble: 3 × 7
#> cyl dispu data_plot figure caption footnote label
#> <dbl> <chr> <list> <gglist> <glue> <glue> <glu>
#> 1 6 cu. in. <tibble [7 × 10]> A ggplot object Horsepower by…
#> 2 4 cu. in. <tibble [11 × 10]> A ggplot object Horsepower by…
#> 3 8 cu. in. <tibble [14 × 10]> A ggplot object Horsepower by…
# You can then show all the figures with the `knit_print()` method.
knit_print(all_plots)Horsepower by displacement for 6 cars
Horsepower by displacement for 4 cars
Horsepower by displacement for 8 cars
ggtibble chunk optionThe ggtibble package registers a knitr
opts_hooks callback that lets you render a
ggtibble with a single chunk option. The chunk below is
equivalent to the one above: the chunk label, fig.cap, and
knit_print() call are all derived from the
ggtibble option value.
``` r
knitr::knit_print(getFromNamespace(".ggtibble_chunk_cache", "ggtibble")[["all_plots"]])
```
<div class="figure">
<img src="/tmp/RtmpOlu7L6/Rbuilde4c35141918/ggtibble/vignettes/v01-introduction_files/figure-html/all_plots-1.png" alt="Horsepower by displacement for 6 cars" width="672" />
<p class="caption">Horsepower by displacement for 6 cars</p>
</div>
<div class="figure">
<img src="/tmp/RtmpOlu7L6/Rbuilde4c35141918/ggtibble/vignettes/v01-introduction_files/figure-html/all_plots-2.png" alt="Horsepower by displacement for 4 cars" width="672" />
<p class="caption">Horsepower by displacement for 4 cars</p>
</div>
<div class="figure">
<img src="/tmp/RtmpOlu7L6/Rbuilde4c35141918/ggtibble/vignettes/v01-introduction_files/figure-html/all_plots-3.png" alt="Horsepower by displacement for 8 cars" width="672" />
<p class="caption">Horsepower by displacement for 8 cars</p>
</div>
The option value is R code given as a character string and is
evaluated in the knit environment, so
ggtibble = "targets::tar_read(all_plots)" also works. This
same syntax works in Quarto, where the auto-generated chunk label is
prefixed with fig- so that @fig-all_plots
cross-references resolve.
ggtibble() also takes footnote and
label glue specifications, built per figure like
caption. A footnote is a markdown note rendered under its
figure: in LaTeX it goes inside the figure float (after the caption, in
a smaller font, and out of the List of Figures), in Typst the figure and
footnote share one unbreakable block, and in HTML and Word it is the
paragraph directly after the figure (Word may still put a page break
between them). A label is the figure’s own identifier for
cross-references and part of the name of its image file; labels must be
unique, ignoring case, and may use letters, digits, hyphens,
underscores, and dots. Under Quarto, start labels with fig-
so that @fig-... references resolve.
A ggtibble with footnotes or labels is written as
markdown, so a chunk that calls knit_print() on it needs
results = "asis"; the ggtibble chunk option
sets that for you.
footnoted_plots <-
ggtibble(
d_plot,
aes(x = disp, y = hp),
outercols = c("cyl", "dispu"),
caption = "Horsepower by displacement for {cyl} cars",
footnote = "Displacement is in {dispu}; each point is one car.",
label = "hp-disp-{cyl}",
labs = list(x = "Displacement ({dispu})", y = "Gross horsepower")
) +
geom_point()Displacement is in cu. in.; each point is one car.
Displacement is in cu. in.; each point is one car.
Displacement is in cu. in.; each point is one car.
ggsave() names the files after the labels when no
filename is given, so
ggsave(plot = footnoted_plots) writes
hp-disp-4.png, hp-disp-6.png, and
hp-disp-8.png.