diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index 89c65c1a..f06b380a 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ -Version: 0.5.0 -Date: 2025-09-21 18:31:22 UTC -SHA: a0d3b9a79ee0f33db7841eba7e3e583cde73ee8e +Version: 0.6.0 +Date: 2025-11-26 21:36:13 UTC +SHA: 3080d0ab861e2cf1f6d463e4784a8d4f6653a6d4 diff --git a/DESCRIPTION b/DESCRIPTION index 1c69ae3c..9628fd94 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,8 +1,8 @@ Package: tinyplot Type: Package Title: Lightweight Extension of the Base R Graphics System -Version: 0.5.0.99 -Date: 2025-09-21 +Version: 0.6.0 +Date: 2025-11-26 Authors@R: c( person( diff --git a/NAMESPACE b/NAMESPACE index 07e97949..2be33118 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -50,6 +50,7 @@ importFrom(grDevices,cairo_pdf) importFrom(grDevices,col2rgb) importFrom(grDevices,colorRampPalette) importFrom(grDevices,convertColor) +importFrom(grDevices,dev.cur) importFrom(grDevices,dev.list) importFrom(grDevices,dev.new) importFrom(grDevices,dev.off) diff --git a/NEWS.md b/NEWS.md index c68e5357..65807b38 100644 --- a/NEWS.md +++ b/NEWS.md @@ -4,7 +4,7 @@ _If you are viewing this file on CRAN, please check the [latest NEWS](https://grantmcdermott.com/tinyplot/NEWS.html) on our website where the formatting is also better._ -## Dev version +## v0.6.0 ### Breaking changes @@ -76,7 +76,7 @@ where the formatting is also better._ `tinyplot()` and that it thus has access to the local definition to all variables such as `x` and `y` etc. (#507 @zeileis) -## 0.5.0 +## v0.5.0 ### New features @@ -138,7 +138,7 @@ where the formatting is also better._ with the CI implementation. - Add a `devcontainer.json` file for remote testing. (#480 @grantmcdermott) -## 0.4.2 +## v0.4.2 ### New features @@ -169,7 +169,7 @@ where the formatting is also better._ can also call them in a base plot layer, relaxing the requirement that they must be called as part of a subsequent plot layer via `tinyplot_add()`. (#422 @grantmcdermott) -## 0.4.1 +## v0.4.1 ### Bug fixes @@ -180,7 +180,7 @@ where the formatting is also better._ - Revert minimum compatible R version to 4.0.0 (#416 @grantmcdermott) -## 0.4.0 +## v0.4.0 ### New features: @@ -278,7 +278,7 @@ where the formatting is also better._ logic was mostly an artifact of development inertia and this new nesting logic should simplify the creation of certain plot types. (#331 @grantmcdermott) -## 0.3.0 +## v0.3.0 ### New features @@ -453,7 +453,7 @@ grouping variables (thanks to @strengjacke for reporting #213). - The new functional type processing system also means that each type now has its own help page (e.g. `?type_hist`, `type_ridge`, etc.) -## 0.2.1 +## v0.2.1 New Features: @@ -502,7 +502,7 @@ Internals: - Revamped formula processing that allows for better sanity checking and edge-case logic. (#197 @zeileis) -## 0.2.0 +## v0.2.0 New features: @@ -530,7 +530,7 @@ Misc: - Various documentation improvements. -## 0.1.0 +## v0.1.0 Our first CRAN submission! This v0.1.0 release includes the following new features and updates: @@ -626,7 +626,7 @@ approach). (#145 @vincentarelbundock & @grantmcdermott) calculates `density` grid coords. (#150 @grantmcdermott) -## 0.0.5 +## v0.0.5 **IMPORTANT BREAKING CHANGE:** @@ -670,7 +670,7 @@ see the following GitHub comment, as well as the discussion that preceded it: https://github.com/grantmcdermott/plot2/issues/22#issuecomment-1928472754 -## 0.0.4 +## v0.0.4 Website: @@ -727,7 +727,7 @@ outer gap to outside of the graphics device unchanged. (#94 @grantmcdermott) - Fix bug where grid wasn't auto-expanding correctly for area plots. (#92 @grantmcdermott) -## 0.0.3 +## v0.0.3 Breaking changes: @@ -765,7 +765,7 @@ Bug fixes: - Setting a global palette, e.g. `palette("ggplot2")` is now respected. (#44 @grantmcdermott) -## 0.0.2 +## v0.0.2 Breaking changes: @@ -792,6 +792,6 @@ Project: - @vincentarelbundock and @zeileis have joined the project as core contributors. 🎉 -## 0.0.1 +## v0.0.1 * Initial release on GitHub. diff --git a/R/align_layer.R b/R/align_layer.R index 51b4d72a..7a837696 100644 --- a/R/align_layer.R +++ b/R/align_layer.R @@ -1,9 +1,24 @@ # Ensure added layers respect the x-axis order of the original plot layer # (e.g., when adding lines or ribbons on top of errorbars) align_layer = function(settings) { - # Retrieve xlabs from current and original layers + # Retrieve xlabs and plot/device metadata from original layer + tinyplot_env = get(".tinyplot_env", envir = parent.env(environment())) + xlabs_orig = tryCatch(get("xlabs_orig", envir = tinyplot_env), error = function(e) NULL) + usr_orig = tryCatch(get("usr_orig", envir = tinyplot_env), error = function(e) NULL) + dev_orig = tryCatch(get("dev_orig", envir = tinyplot_env), error = function(e) NULL) + + # Validate that we're adding to the same plot (not a stale xlabs from previous plot) + if (is.null(usr_orig) || is.null(dev_orig) || dev_orig != dev.cur()) { + return(invisible()) + } + # Normalize current usr for comparison (accounting for flipped plots) + usr_layer = if (isTRUE(settings$flip)) par("usr")[c(3,4,1,2)] else par("usr") + if (!identical(usr_orig, usr_layer)) { + return(invisible()) + } + + # xlabs of current layer xlabs_layer = settings[["xlabs"]] - xlabs_orig = get("xlabs", envir = get(".tinyplot_env", envir = parent.env(environment()))) # Only adjust if original layer has named xlabs if (!is.null(names(xlabs_orig))) { diff --git a/R/tinyplot.R b/R/tinyplot.R index f60d1ab8..e7aa6bd1 100644 --- a/R/tinyplot.R +++ b/R/tinyplot.R @@ -368,7 +368,7 @@ #' out existing `plot` calls for `tinyplot` (or its shorthand alias `plt`), #' without causing unexpected changes to the output. #' -#' @importFrom grDevices axisTicks adjustcolor cairo_pdf colorRampPalette extendrange palette palette.colors palette.pals hcl.colors hcl.pals xy.coords png jpeg pdf svg dev.off dev.new dev.list +#' @importFrom grDevices axisTicks adjustcolor cairo_pdf colorRampPalette dev.cur dev.list dev.off dev.new extendrange hcl.colors hcl.pals jpeg palette palette.colors palette.pals pdf png svg xy.coords #' @importFrom graphics abline arrows axis Axis axTicks box boxplot grconvertX grconvertY hist lines mtext par plot.default plot.new plot.window points polygon polypath segments rect text title #' @importFrom utils modifyList head tail #' @importFrom stats na.omit setNames @@ -871,7 +871,7 @@ tinyplot.default = function( # ensure axis aligment of any added layers if (!add) { - assign("xlabs", settings[["xlabs"]], envir = get(".tinyplot_env", envir = parent.env(environment()))) + assign("xlabs_orig", settings[["xlabs"]], envir = get(".tinyplot_env", envir = parent.env(environment()))) } else { align_layer(settings) } @@ -1340,6 +1340,14 @@ tinyplot.default = function( # if (!add) { + # Capture device and usr before recordGraphics (in current plot context) + current_dev = dev.cur() + current_usr = if (isTRUE(settings$flip)) par("usr")[c(3,4,1,2)] else par("usr") + + # Store usr and dev for validating layer alignment + assign("usr_orig", current_usr, envir = get(".tinyplot_env", envir = parent.env(environment()))) + assign("dev_orig", current_dev, envir = get(".tinyplot_env", envir = parent.env(environment()))) + recordGraphics( { apar = par(no.readonly = TRUE) diff --git a/README.md b/README.md index 826d33b2..a45e03fe 100644 --- a/README.md +++ b/README.md @@ -93,8 +93,8 @@ tinyplot(Sepal.Length ~ Petal.Length | Species, data = iris) # formu If you would prefer to save on a few keystrokes, you can use the shorthand `plt()` alias instead of typing out `tinyplot()` in full. -Here’s the same plot with this shorthand alias, plus a few aesthetic -tweaks: +Here’s the same plot with this shorthand `plt()` alias, as well as an +added `"lm"` layer and a few aesthetic tweaks: ``` r plt( @@ -103,6 +103,7 @@ plt( palette = "dark", pch = 16, grid = TRUE, frame = FALSE ) +plt_add(type = "lm") ``` @@ -114,6 +115,7 @@ built-in themes for convenient plot customization: tinytheme("clean2") plt(Sepal.Length ~ Petal.Length | Species, data = iris) +plt_add(type = "lm") ``` -y -x - - - - - - --10 -0 -10 -20 -30 - - - - - -(Intercept) -hp -factor(cyl)6 -factor(cyl)8 - +y +x + + + + + + +-10 +0 +10 +20 +30 + + + + + +(Intercept) +hp +factor(cyl)6 +factor(cyl)8 + - - + + - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/inst/tinytest/test-type_pointrange.R b/inst/tinytest/test-type_pointrange.R index ae87a228..5ea61637 100644 --- a/inst/tinytest/test-type_pointrange.R +++ b/inst/tinytest/test-type_pointrange.R @@ -64,10 +64,10 @@ fun = function() { y ~ x, ymin = ymin, ymax = ymax, data = coefs, type = "pointrange", - theme = "basic", + theme = "classic", flip = TRUE ) tinyplot_add(type = "ribbon") - tinyplot_add(type = "hline", lty = 2) + tinyplot_add(type = "vline", lty = 2) } expect_snapshot_plot(fun, label = "pointrange_with_layers_flipped") diff --git a/man/figures/README-quickstart2-1.png b/man/figures/README-quickstart2-1.png index d91ee9eb..768ea50a 100644 Binary files a/man/figures/README-quickstart2-1.png and b/man/figures/README-quickstart2-1.png differ diff --git a/man/figures/README-quickstart3-1.png b/man/figures/README-quickstart3-1.png index e4527d66..3dad29db 100644 Binary files a/man/figures/README-quickstart3-1.png and b/man/figures/README-quickstart3-1.png differ diff --git a/man/figures/README-quickstart4-1.png b/man/figures/README-quickstart4-1.png index 88ea5ce7..d162c144 100644 Binary files a/man/figures/README-quickstart4-1.png and b/man/figures/README-quickstart4-1.png differ diff --git a/man/figures/README-quickstart5-1.png b/man/figures/README-quickstart5-1.png index 03724cd3..8136b05d 100644 Binary files a/man/figures/README-quickstart5-1.png and b/man/figures/README-quickstart5-1.png differ diff --git a/man/figures/README-quickstart_theme-1.png b/man/figures/README-quickstart_theme-1.png index c52f451a..eb076156 100644 Binary files a/man/figures/README-quickstart_theme-1.png and b/man/figures/README-quickstart_theme-1.png differ diff --git a/man/type_errorbar.Rd b/man/type_errorbar.Rd index c6384d7e..8d835d67 100644 --- a/man/type_errorbar.Rd +++ b/man/type_errorbar.Rd @@ -60,10 +60,13 @@ tinyplot(est ~ term, ymin = lwr, ymax = upr, data = coefs, # For flipped errobar / pointrange plots, it is recommended to use a dynamic # theme that applies horizontal axis tick labels + +tinytheme("classic") tinyplot(est ~ term, ymin = lwr, ymax = upr, data = coefs, type = "errorbar", - flip = TRUE, theme = "classic") + flip = TRUE) tinyplot_add(type = 'vline', lty = 2) +tinytheme("basic") # back to basic theme for the remaining examples # ## Dodging groups @@ -104,7 +107,7 @@ tinyplot(estimate ~ term | model, # Aside 2: layering # For layering on top of dodged plots, rather pass the dodging arguments # through the top-level call if you'd like the dodging behaviour to be -# inherited automatically by the add layers. +# inherited automatically by the added layers. tinyplot(estimate ~ term | model, ymin = conf.low, ymax = conf.high,