Skip to content

Commit 825647f

Browse files
Ephemeral theme arg (#484)
* ephemeral theme argument * docs * vignette * news * add test
1 parent 113e594 commit 825647f

File tree

8 files changed

+544
-3
lines changed

8 files changed

+544
-3
lines changed

NEWS.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@ where the formatting is also better._
2222
`boxplot(x)`. (#454 @zeileis)
2323
- `type_errorbar()` and `type_point_range()` get a `dodge` argument.
2424
(#461 @vincentarelbundock)
25+
- The new `tinyplot(..., theme = <theme>)` argument enables users to invoke
26+
ephemeral themes as an alternative to the persistent themes that follow
27+
`tinytheme(<theme>)`. (#483 @grantmcdermott)
2528

2629
### Bug fixes
2730

R/tinyplot.R

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -349,6 +349,9 @@
349349
#' `width` (above) apply, e.g. will default to `tpar("file.height")` if not
350350
#' specified.
351351
#' @param asp the y/xy/x aspect ratio, see `plot.window`.
352+
#' @param theme keyword string (e.g. `"clean"`) or list defining a theme. Passed
353+
#' on to [`tinytheme`], but reset upon exit so that the theme effect is only
354+
#' temporary. Useful for invoking ephemeral themes.
352355
#' @param ... other graphical parameters. If `type` is a character specification
353356
#' (such as `"hist"`) then any argument names that match those from the corresponding
354357
#' `type_*()` function (such as \code{\link{type_hist}}) are passed on to that.
@@ -634,6 +637,7 @@ tinyplot.default = function(
634637
width = NULL,
635638
height = NULL,
636639
asp = NA,
640+
theme = NULL,
637641
...) {
638642

639643

@@ -674,6 +678,22 @@ tinyplot.default = function(
674678
}
675679
set_saved_par(when = "before", opar)
676680

681+
# Ephemeral theme
682+
if (!is.null(theme)) {
683+
# browser()
684+
if (is.character(theme) && length(theme) == 1) {
685+
tinytheme(theme)
686+
} else if (is.list(theme)) {
687+
do.call(tinytheme, theme)
688+
} else {
689+
warning('Argument `theme` must be a character of length 1 (e.g. "clean"), or a list. Ignoring.')
690+
}
691+
dtheme = theme_default
692+
otheme = opar[names(dtheme)]
693+
694+
on.exit(do.call(tinytheme, otheme), add = TRUE)
695+
}
696+
677697

678698
#
679699
## devices and files -----

R/tinytheme.R

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,11 @@
3434
#' @details
3535
#' Sets a list of graphical parameters using `tpar()`
3636
#'
37+
#' Note that themes are persistent and will be applied to all subsequent plots.
3738
#' To reset the theme to default settings (no customization), call `tinytheme()`
38-
#' without arguments.
39+
#' without arguments. Altenatively, invoke the `tinyplot(..., theme = <theme>)`
40+
#' argument for an ephemeral theme that is automatically reset at the end of the
41+
#' plot call.
3942
#'
4043
#' **Caveat emptor:** Themes are a somewhat experimental feature of `tinyplot`.
4144
#' While we feel confident that themes should work as expected for most
@@ -65,6 +68,9 @@
6568
#' # Set a theme
6669
#' tinytheme("bw")
6770
#' p()
71+
#'
72+
#' # A set theme is persistent and will apply to subsequent plots
73+
#' tinyplot(0:10)
6874
#'
6975
#' # Try a different theme
7076
#' tinytheme("dark")
@@ -86,6 +92,10 @@
8692
#' tinytheme()
8793
#' p()
8894
#'
95+
#' # For an ephemeral theme, use `tinyplot(..., theme = <theme>)` directly
96+
#' tinyplot(0:10, theme = "clean", main = "This theme is ephemeral")
97+
#' tinyplot(10:0, main = "See, no more theme")
98+
#'
8999
#' # Themes showcase
90100
#' ## We'll use a slightly more intricate plot (long y-axis labs and facets)
91101
#' ## to demonstrate dynamic margin adjustment etc.

inst/tinytest/_tinysnapshot/tinytheme_ephemeral.svg

Lines changed: 464 additions & 0 deletions
Loading

inst/tinytest/test-tinytheme.R

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ using("tinysnapshot")
33

44
tinytheme()
55

6-
76
thms = eval(formals(tinytheme)$theme)
87

98
for (thm in thms) {
@@ -152,3 +151,19 @@ expect_snapshot_plot(f, label = "tinytheme_dynamic_clean_spineplot")
152151
## reset
153152

154153
tinytheme()
154+
155+
156+
#
157+
## ephemeral theme
158+
159+
f = function() {
160+
opar = par(mfrow = c(1, 2))
161+
plt(Sepal.Length ~ Petal.Length | Species, data = iris,
162+
main = "Ephemeral theme", theme = "clean", legend = FALSE)
163+
plt_add(type = "lm")
164+
plt(Sepal.Length ~ Petal.Length | Species, data = iris,
165+
main = "Revert to old theme", legend = FALSE)
166+
plt_add(type = "lm")
167+
par(opar)
168+
}
169+
expect_snapshot_plot(f, label = "tinytheme_ephemeral")

man/tinyplot.Rd

Lines changed: 5 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

man/tinytheme.Rd

Lines changed: 11 additions & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

vignettes/themes.qmd

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,20 @@ tinytheme()
8383
tinyplot(mpg ~ hp, data = mtcars, main = "Fuel efficiency vs. horsepower")
8484
```
8585

86+
### Aside: ephemeral themes
87+
88+
We expect that users will generally want to set a persistent theme for all
89+
(most) of their plots. But it is also possible to set a ephemeral theme for a
90+
particular plot by calling the `tinyplot(..., theme = <theme>)` argument
91+
directly.
92+
93+
```{r}
94+
#| layout-ncol: 2
95+
tinyplot(mpg ~ hp, data = mtcars, main = "Ephemeral theme", theme = "clean")
96+
tinyplot(mpg ~ hp, data = mtcars, main = "Back to the default")
97+
```
98+
99+
86100

87101
### Gallery
88102

0 commit comments

Comments
 (0)