Skip to content

Commit d2f3b38

Browse files
CRAN v0.1.0 submission (#151)
* NEWS * NEWS and version bump * CRAN comments and .Rbuildignore update * CRAN submission (1st time) * Anticipatory install updates in README * Simplify package meta docs * Docs: Add return values and other updates per CRAN request * Minor cleanups * Fixes #149 * README tweak * tweak * More README tweaks * Add ribbon.alpha to tpar * document * Add get_orig_par and supporting functions * closes #150 * tweak * Add get_saved_par. Closes #152. * Easy alpha adjustment. Closes #129. * README tweak * fix README footnotes - be explicit with `quarto render README.qmd --to gfm ` * typo * typo * prep cran submission * submission SHA
1 parent 7218f7b commit d2f3b38

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

55 files changed

+1966
-723
lines changed

.Rbuildignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,3 +17,6 @@ README_files/
1717
^_quarto$
1818
vignettes/
1919
^LICENSE\.md$
20+
^cran-comments\.md$
21+
^CRAN-SUBMISSION$
22+
#inst/tinytest/

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,5 @@ SCRATCH
5555
^_quarto$
5656

5757
_quarto
58+
59+
/.quarto/

CRAN-SUBMISSION

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
Version: 0.1.0
2+
Date: 2024-06-19 18:17:25 UTC
3+
SHA: 561b24cb0be3549f88efdc7aa527181f7e6b3327

DESCRIPTION

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,16 @@
11
Package: tinyplot
22
Type: Package
33
Title: Lightweight Extension of the Base R Graphics System
4-
Version: 0.0.5.9008
4+
Version: 0.1.0
5+
Date: 2024-06-19
56
Authors@R:
67
c(
78
person(
89
given = "Grant",
910
family = "McDermott",
1011
role = c("aut", "cre"),
11-
email = "gmcd@amazon.com"
12+
email = "gmcd@amazon.com",
13+
comment = c(ORCID = "0000-0001-7883-8573")
1214
),
1315
person(
1416
given = "Vincent",
@@ -32,7 +34,7 @@ Authors@R:
3234
)
3335
)
3436
Description: Lightweight extension of the base R graphics system, with support
35-
for automatic legends, facetting, and several other enhancements.
37+
for automatic legends, facets, and various other enhancements.
3638
License: Apache License (>= 2)
3739
Depends:
3840
R (>= 4.0)
@@ -54,8 +56,6 @@ Suggests:
5456
knitr
5557
Encoding: UTF-8
5658
RoxygenNote: 7.3.1
57-
URL: https://grantmcdermott.com/tinyplot/,
58-
http://grantmcdermott.com/tinyplot/
59+
URL: https://grantmcdermott.com/tinyplot/
5960
BugReports: https://github.com/grantmcdermott/tinyplot/issues
60-
VignetteBuilder: knitr
6161
Roxygen: list(markdown = TRUE)

NAMESPACE

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ S3method(tinyplot,default)
44
S3method(tinyplot,density)
55
S3method(tinyplot,formula)
66
export(draw_legend)
7+
export(get_saved_par)
78
export(plt)
89
export(tinyplot)
910
export(tpar)

NEWS.md

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,25 @@
11
# News
22

3-
## 0.0.5.9008 (development version)
3+
## 0.1.0
4+
5+
Our first CRAN submission! This v0.1.0 release includes the following new
6+
features and updates:
47

58
License:
69

710
- Formally switch to Apache 2.0 license. (#141 @grantmcdermott)
811

12+
Breaking changes:
13+
14+
- To ensure consistent "dot.case" style for all `tinyplot()` function arguments,
15+
the following two arguments have been renamed (`old` => `new`):
16+
- `par_restore` => `restore.par` (note the change in word order too!)
17+
- `ribbon_alpha` => `ribbon.alpha`
18+
19+
We don't believe that these two arguments are much used in practice. So
20+
hopefully it will only have a negligible effect on existing `tinyplot` code in
21+
the wild, even though it is a breaking change. (#149 @grantmcdermott)
22+
923
New features:
1024

1125
- Gradient legends are now supported if a continuous variable is passed to
@@ -22,7 +36,11 @@ default. Thanks to @zeileis for the suggestion. (#130 @grantmcdermott)
2236
automatically vary line widths by group. (#134 @grantmcdermott)
2337
- `tpar()` now accepts standard `par()` arguments in addition to the
2438
`tinyplot`-specific ones. This allows users to set or query graphical parameters
25-
via a single convenience function, instead having to invoke `tpar` and `par` separately.
39+
via a single convenience function, instead having to invoke `tpar` and `par`
40+
separately. (#140 @grantmcdermott)
41+
- As an aside, `tpar()` has gained some additional parameters for fine-grained
42+
control of global plot defaults, including `grid`, `ribbon.alpha`, and various
43+
`file.*` parameters (see next bullet point).
2644
- Users can write plots directly to disk using the new `file` argument,
2745
alongside corresponding `width` and `height` arguments for output customization
2846
(both of which are defined in inches). For example,
@@ -32,9 +50,27 @@ external graphics devices like `png()`, `pdf()`, etc. But it may prove more
3250
convenient, since the current global graphics parameters held in `(t)par()` are
3351
carried over to the external device too and don't need to be reset. Note that
3452
the appropriate device type is determined automatically by the file extension,
35-
which must be one of ".png", ".jpg" (".jpeg"), ".pdf", or ".svg". (#143
53+
which must be one of ".png", ".jpg" (".jpeg"), ".pdf", or ".svg".
54+
(#143 @grantmcdermott)
55+
- We have a shiny new `tinyplot` logo. (#148 @grantmcdermott)
56+
- The new `get_saved_par()` function can be used to retrieve the `par` settings
57+
from immediately before or immediately after the preceding `tinyplot` call.
58+
This function replaces some older (non-exported) internal functions that
59+
`tinyplot` was using to restore and control `par` environments. But it could
60+
also prove help to end users who are looking for additional ways to restore
61+
`par` settings after the fact. See `?get_saved_par` for some examples. (#152
62+
@grantmcdermott)
63+
- `tinyplot`/`plt` gaina a new `alpha = <numeric[0,1]>` convenience argument for
64+
adding transparency to plot elements and colours. Example use:
65+
`plt(rnorm(1e3), pch = 19, alpha = 0.3)`. (#129 @grantmcdermott)
66+
- Similar to the preceding news item, transparency can be added to (grouped)
67+
background fill by passing `bg` (or its alias, `fill`) a numeric in the range
68+
`[0,1]`. This feature has the same effect as `bg = "by"` except for the added
69+
transparency. Example use:
70+
`plt(lat ~ long | depth, data = quakes, pch = 21, cex = 2, bg = 0.2)`. (#129
3671
@grantmcdermott)
3772

73+
3874
Bug fixes:
3975

4076
- Fixed bug that prevented `tpar(facet.x = ...)` args from being passed forward
@@ -56,6 +92,8 @@ CRAN's recommended 5 MB limit. Please note that local testing of the package
5692
requires adding the `NOT_CRAN=TRUE` environment variable to your .Renviron file
5793
(or, exporting it in your .bashrc/.zshrc/etc. dotfile if you prefer that
5894
approach). (#145 @vincentarelbundock & @grantmcdermott)
95+
- Update some test snapshots to match slight changes in the way that R 4.4.0
96+
calculates `density` grid coords. (#150 @grantmcdermott)
5997

6098

6199
## 0.0.5

R/by_aesthetics.R

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
by_col = function(ngrps = 1L, col = NULL, palette = NULL, gradient = NULL, ordered = NULL) {
1+
by_col = function(ngrps = 1L, col = NULL, palette = NULL, gradient = NULL, ordered = NULL, alpha = NULL) {
22

33
if (is.null(ordered)) ordered = FALSE
4+
if (is.null(alpha)) alpha = 1
45
if (is.null(gradient)) gradient = FALSE
56
if (isTRUE(gradient)) {
67
ngrps = 100L
@@ -37,8 +38,8 @@ by_col = function(ngrps = 1L, col = NULL, palette = NULL, gradient = NULL, order
3738
if (is.null(palette)) {
3839

3940
if (ngrps <= length(palette()) && isFALSE(ordered) && isFALSE(gradient)) {
40-
palette_fun = function() palette() # must be function to avoid arg ambiguity
41-
args = list()
41+
palette_fun = function(alpha) adjustcolor(palette(), alpha) # must be function to avoid arg ambiguity
42+
args = list(alpha = alpha)
4243
} else {
4344
if (ngrps <= 8 && isFALSE(ordered)) { # ngrps < 100 so we know gradient is FALSE too
4445
palette = "R4"
@@ -58,7 +59,7 @@ by_col = function(ngrps = 1L, col = NULL, palette = NULL, gradient = NULL, order
5859
}
5960

6061
}
61-
args = list(n = ngrps, palette = palette)
62+
args = list(n = ngrps, palette = palette, alpha = alpha)
6263
}
6364

6465
} else {
@@ -71,7 +72,7 @@ by_col = function(ngrps = 1L, col = NULL, palette = NULL, gradient = NULL, order
7172
if (pal_match < 1L) stop("'palette' is ambiguous")
7273
palette_fun = palette.colors
7374
if (isTRUE(gradient)) {
74-
palette_fun2 = function(n, palette) colorRampPalette(palette.colors(palette = palette))(n)
75+
palette_fun2 = function(n, palette, alpha) colorRampPalette(palette.colors(palette = palette, alpha = alpha))(n)
7576
palette_fun = palette_fun2
7677
}
7778
} else {
@@ -87,7 +88,7 @@ by_col = function(ngrps = 1L, col = NULL, palette = NULL, gradient = NULL, order
8788
)
8889
}
8990
}
90-
args = list(n = ngrps, palette = palette)
91+
args = list(n = ngrps, palette = palette, alpha = alpha)
9192

9293
} else if (class(palette) %in% c("call", "name")) {
9394

R/draw_legend.R

Lines changed: 18 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,17 +4,17 @@
44
#' outside the plotting area) and drawing of legend.
55
#'
66
#' @md
7-
#' @param legend Legend placement keyword or list, passed down from `tinyplot`.
7+
#' @param legend Legend placement keyword or list, passed down from [tinyplot].
88
#' @param legend_args Additional legend arguments to be passed to `legend()`.
99
#' @param by_dep The (deparsed) "by" grouping variable name.
1010
#' @param lgnd_labs The labels passed to `legend(legend = ...)`.
11-
#' @param type Plotting type(s), passed down from `tinyplot`.
12-
#' @param pch Plotting character(s), passed down from `tinyplot`.
13-
#' @param lty Plotting linetype(s), passed down from `tinyplot`.
14-
#' @param lwd Plotting line width(s), passed down from `tinyplot`.
15-
#' @param col Plotting colour(s), passed down from `tinyplot`.
16-
#' @param bg Plotting character background fill colour(s), passed down from `tinyplot`.
17-
#' @param cex Plotting character expansion(s), passed down from `tinyplot`.
11+
#' @param type Plotting type(s), passed down from [tinyplot].
12+
#' @param pch Plotting character(s), passed down from [tinyplot].
13+
#' @param lty Plotting linetype(s), passed down from [tinyplot].
14+
#' @param lwd Plotting line width(s), passed down from [tinyplot].
15+
#' @param col Plotting colour(s), passed down from [tinyplot].
16+
#' @param bg Plotting character background fill colour(s), passed down from [tinyplot].
17+
#' @param cex Plotting character expansion(s), passed down from [tinyplot].
1818
#' @param gradient Logical indicating whether a continuous gradient swatch
1919
#' should be used to represent the colors.
2020
#' @param lmar Legend margins (in lines). Should be a numeric vector of the form
@@ -26,10 +26,15 @@
2626
#' @param has_sub Logical. Does the plot have a sub-caption. Only used if
2727
#' keyword position is "bottom!", in which case we need to bump the legend
2828
#' margin a bit further.
29-
#' @param new_plot Should we be calling plot.new internally?
29+
#' @param new_plot Logical. Should we be calling plot.new internally?
30+
#'
31+
#' @returns No return value, called for side effect of producing a(n empty) plot
32+
#' with a legend in the margin.
33+
#'
3034
#' @importFrom graphics grconvertX grconvertY rasterImage strwidth
3135
#' @importFrom grDevices as.raster recordGraphics
3236
#' @importFrom utils modifyList
37+
#'
3338
#' @examples
3439
#'
3540
#' oldmar = par("mar")
@@ -225,7 +230,7 @@ draw_legend = function(
225230
# requires additional space
226231
omar[2] = par("mgp")[1] + 1*par("cex.lab")
227232
}
228-
par(mar = omar) ## TEST
233+
par(mar = omar)
229234

230235
if (isTRUE(new_plot)) plot.new()
231236

@@ -292,13 +297,13 @@ draw_legend = function(
292297
## drawn, otherwise the inset calculation---which is based in the legend
293298
## width---will be off the first time.
294299
if (outer_bottom) {
295-
omar[1] = par("mgp")[1] + 1*par("cex.lab") ## TEST
296-
if (isTRUE(has_sub)) omar[1] = omar[1] + 1*par("cex.sub") ## TEST
300+
omar[1] = par("mgp")[1] + 1*par("cex.lab")
301+
if (isTRUE(has_sub)) omar[1] = omar[1] + 1*par("cex.sub")
297302
} else {
298303
## For "top!", the logic is slightly different: We don't expand the outer
299304
## margin b/c we need the legend to come underneath the main title. So
300305
## we rather expand the existing inner margin.
301-
ooma[3] = ooma[3] + topmar_epsilon ## TESTING
306+
ooma[3] = ooma[3] + topmar_epsilon
302307
par(oma = ooma)
303308
}
304309
par(mar = omar)

R/get_saved_par.R

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
1+
#' @title Retrieve the saved graphical parameters
2+
#'
3+
#' @description Convenience function for retrieving the graphical parameters
4+
#' (i.e., the full list of `tag = value` pairs held in
5+
#' \code{\link[graphics]{par}}) from either immediately before or
6+
#' immediately after the most recent [tinyplot] call.
7+
#'
8+
#' @param when character. From when should the saved parameters be retrieved?
9+
#' Either "before" (the default) or "after" the preceding `tinyplot` call.
10+
#'
11+
#' @details A potential side-effect of [tinyplot] is that it can change a user's
12+
#' \code{\link[graphics]{par}} settings. For example, it may adjust the inner
13+
#' and outer plot margins to make space for an automatic legend; see
14+
#' [draw_legend]. While it is possible to immediately restore the original
15+
#' \code{\link[graphics]{par}} settings upon exit via the
16+
#' `tinyplot(..., restore.par = TRUE)` argument, this is not the default
17+
#' behaviour. The reason being that we need to preserve the adjusted parameter
18+
#' settings in case users want to add further graphical annotations to their
19+
#' plot (e.g., \code{\link[graphics]{abline}}, \code{\link[graphics]{text}},
20+
#' etc.) Nevertheless, it may still prove desirable to recall and reset these
21+
#' original graphical parameters after the fact (e.g., once all these extra
22+
#' annotations have been added). That is the purpose of this [get_saved_par]
23+
#' function.
24+
#'
25+
#' Of course, users may prefer to manually capture and reset graphical
26+
#' parameters, as per the standard method described in the
27+
#' \code{\link[graphics]{par}} documentation. For example:
28+
#'
29+
#' ```
30+
#' op = par(no.readonly = TRUE) # save current par settings
31+
#' # <do lots of (tiny)plotting>
32+
#' par(op) # reset original pars
33+
#' ```
34+
#'
35+
#' This standard manual approach may be safer than [get_saved_par] because it
36+
#' offers more precise control. Specifically, the value of [get_saved_par]
37+
#' itself will be reset after ever new [tinyplot] call; i.e. it may inherit an
38+
#' already-changed set of parameters. Users should bear these trade-offs in
39+
#' mind when deciding which approach to use. As a general rule,
40+
#' [get_saved_par] offers the convenience of resetting the original
41+
#' \code{\link[graphics]{par}} settings even if a user forgot to save them
42+
#' beforehand. But one should avoid invoking it after a series of consecutive
43+
#' [tinyplot] calls.
44+
#'
45+
#' Finally, note that users can always call \code{\link[grDevices]{dev.off}}
46+
#' to reset all \code{\link[graphics]{par}} settings to their defaults.
47+
#'
48+
#' @returns A list of \code{\link[graphics]{par}} settings.
49+
#'
50+
#' @examples
51+
#' #
52+
#' # Contrived example where we draw a grouped scatterplot with a legend and
53+
#' # manually add corresponding best fit lines for each group...
54+
#' #
55+
#'
56+
#' # First draw the grouped scatterplot
57+
#' tinyplot(Sepal.Length ~ Petal.Length | Species, iris)
58+
#'
59+
#' # Preserving adjusted par settings is good for adding elements to our plot
60+
#' for (s in levels(iris$Species)) {
61+
#' abline(
62+
#' lm(Sepal.Length ~ Petal.Length, iris, subset = Species==s),
63+
#' col = which(levels(iris$Species)==s)
64+
#' )
65+
#' }
66+
#'
67+
#' # Get saved par from before the preceding tinyplot call (but don't use yet)
68+
#' sp = get_saved_par("before")
69+
#'
70+
#' # Note the changed margins will affect regular plots too, which is probably
71+
#' # not desirable
72+
#' plot(1:10)
73+
#'
74+
#' # Reset the original parameters (could use `par(sp)` here)
75+
#' tpar(sp)
76+
#' # Redraw our simple plot with our corrected right margin
77+
#' plot(1:10)
78+
#'
79+
#' #
80+
#' # Quick example going the other way, "correcting" for par.restore = TRUE...
81+
#' #
82+
#'
83+
#' tinyplot(Sepal.Length ~ Petal.Length | Species, iris, restore.par = TRUE)
84+
#' # Our added best lines will be wrong b/c of misaligned par
85+
#' for (s in levels(iris$Species)) {
86+
#' abline(
87+
#' lm(Sepal.Length ~ Petal.Length, iris, subset = Species==s),
88+
#' col = which(levels(iris$Species)==s), lty = 2
89+
#' )
90+
#' }
91+
#' # grab the par settings from the _end_ of the preceding tinyplot call to fix
92+
#' tpar(get_saved_par("after"))
93+
#' # now the best lines are correct
94+
#' for (s in levels(iris$Species)) {
95+
#' abline(
96+
#' lm(Sepal.Length ~ Petal.Length, iris, subset = Species==s),
97+
#' col = which(levels(iris$Species)==s)
98+
#' )
99+
#' }
100+
#'
101+
#' # reset again to original saved par settings before exit
102+
#' tpar(sp)
103+
#'
104+
#' @export
105+
get_saved_par <- function(when = c("before", "after")) {
106+
when = match.arg(when)
107+
par_env_name = paste0(".saved_par_", when)
108+
return(get(par_env_name, envir = get(".tinyplot_env", envir = parent.env(environment()))))
109+
}
110+
111+
# (non-exported) companion function(s) for setting the original pars
112+
set_saved_par <- function(when = c("before", "after"), value) {
113+
when = match.arg(when)
114+
par_env_name = paste0(".saved_par_", when)
115+
assign(par_env_name, value, envir = get(".tinyplot_env", envir = parent.env(environment())))
116+
}

0 commit comments

Comments
 (0)