From 52afd68312bb00e93132bdd0c216e10362af264f Mon Sep 17 00:00:00 2001 From: Achim Zeileis Date: Sun, 22 Mar 2026 12:24:53 +0100 Subject: [PATCH 01/22] add tinyplot() method for 'ts' time series objects --- R/tinyplot.ts.R | 69 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 R/tinyplot.ts.R diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R new file mode 100644 index 000000000..82625b9f2 --- /dev/null +++ b/R/tinyplot.ts.R @@ -0,0 +1,69 @@ +#' tinyplot Method for Plotting ts Objects (Time Series) +#' +#' @description Convenience interface for visualizing ts objects +#' (time sereis with tinyplot. +#' +#' @details Internally the time series object is converted to a long +#' data frame with columns `Time` (time index), `Value` (observations), +#' and `Series` (factor with column labels). Depending on the settings +#' of `facet` this data frame is visualized either with the formula +#' `Value ~ Time` or `Value ~ Time | Series`. See the `facet` argument +#' description for more details and the examples for some illustrations. +#' +#' @param x an object of class `"ts"`. +#' @param facet specification of `facet` for `tinyplot.formula`. The +#' default in the `tinyplot` method is to use `facet = NULL` for univariate +#' series and `facet = ~ Series` (equivalent to `facet = "by"`) for multivariate series. +#' @param type,facet.args,ylab,... further arguments passed to `tinyplot`. +#' +#' @examples +#' tinytheme("clean2") +#' +#' ## univariate series +#' tinyplot(Nile) +#' +#' ## multivariate +#' tinyplot(EuStockMarkets) ## multiple, same color, free scales +#' tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale +#' tinyplot(EuStockMarkets, facet = "by") ## multiple, separate colors, free scales +#' tinyplot(EuStockMarkets, facet = NULL) ## single, separate colors +#' +#' ## further variations +#' tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) +#' tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) +#' +#' tinytheme() ## reset +#' +#' @export +tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), ylab = "", ...) { + ## basic object properties + n = NROW(x) + k = NCOL(x) + lab = deparse(substitute(x)) + if (k > 1L) lab = paste(lab, 1L:k, sep = ".") + if (!is.null(colnames(x))) lab = colnames(x) + + ## convert to long data.frame + df = data.frame( + Time = rep.int(as.numeric(time(x)), k), + Value = as.numeric(x), + Series = factor(rep(1L:k, each = n), labels = lab) + ) + + ## default for facet + single = k == 1L + if(missing(facet)) { + auto = TRUE + facet = if(single) NULL else ~ Series + } else { + auto = FALSE + } + if (is.null(facet)) facet.args = NULL + + ## call tinyplot + if(single | (!is.null(facet) & auto)) { + tinyplot(Value ~ Time, data = df, facet = facet, facet.args = facet.args, type = type, ylab = ylab, ...) + } else { + tinyplot(Value ~ Time | Series, data = df, facet = facet, facet.args = facet.args, type = type, ylab = ylab, ...) + } +} From e02feb4475e45591f4547568ac8023a598d95b4c Mon Sep 17 00:00:00 2001 From: Achim Zeileis Date: Sun, 22 Mar 2026 12:35:46 +0100 Subject: [PATCH 02/22] add documentation --- NAMESPACE | 1 + man/tinyplot.ts.Rd | 48 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) create mode 100644 man/tinyplot.ts.Rd diff --git a/NAMESPACE b/NAMESPACE index 30d3736e7..486ba883e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -3,6 +3,7 @@ S3method(tinyplot,default) S3method(tinyplot,density) S3method(tinyplot,formula) +S3method(tinyplot,ts) export(draw_legend) export(get_saved_par) export(plt) diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd new file mode 100644 index 000000000..752897f86 --- /dev/null +++ b/man/tinyplot.ts.Rd @@ -0,0 +1,48 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/tinyplot.ts.R +\name{tinyplot.ts} +\alias{tinyplot.ts} +\title{tinyplot Method for Plotting ts Objects (Time Series)} +\usage{ +\method{tinyplot}{ts}(x, facet, type = "l", facet.args = list(free = TRUE), ylab = "", ...) +} +\arguments{ +\item{x}{an object of class \code{"ts"}.} + +\item{facet}{specification of \code{facet} for \code{tinyplot.formula}. The +default in the \code{tinyplot} method is to use \code{facet = NULL} for univariate +series and \code{facet = ~ Series} (equivalent to \code{facet = "by"}) for multivariate series.} + +\item{type, facet.args, ylab, ...}{further arguments passed to \code{tinyplot}.} +} +\description{ +Convenience interface for visualizing ts objects +(time sereis with tinyplot. +} +\details{ +Internally the time series object is converted to a long +data frame with columns \code{Time} (time index), \code{Value} (observations), +and \code{Series} (factor with column labels). Depending on the settings +of \code{facet} this data frame is visualized either with the formula +\code{Value ~ Time} or \code{Value ~ Time | Series}. See the \code{facet} argument +description for more details and the examples for some illustrations. +} +\examples{ +tinytheme("clean2") + +## univariate series +tinyplot(Nile) + +## multivariate +tinyplot(EuStockMarkets) ## multiple, same color, free scales +tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale +tinyplot(EuStockMarkets, facet = "by") ## multiple, separate colors, free scales +tinyplot(EuStockMarkets, facet = NULL) ## single, separate colors + +## further variations +tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) +tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) + +tinytheme() ## reset + +} From e83ca71b88c58b8473012172c4c2dc213f24808f Mon Sep 17 00:00:00 2001 From: Achim Zeileis Date: Sun, 22 Mar 2026 17:48:28 +0100 Subject: [PATCH 03/22] import time() extractor --- NAMESPACE | 1 + R/tinyplot.ts.R | 7 ++++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/NAMESPACE b/NAMESPACE index 486ba883e..f65fd4586 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -123,6 +123,7 @@ importFrom(stats,quantile) importFrom(stats,setNames) importFrom(stats,spline) importFrom(stats,terms) +importFrom(stats,time) importFrom(stats,weighted.mean) importFrom(tools,file_ext) importFrom(utils,globalVariables) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index 82625b9f2..7576049a7 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -27,13 +27,14 @@ #' tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale #' tinyplot(EuStockMarkets, facet = "by") ## multiple, separate colors, free scales #' tinyplot(EuStockMarkets, facet = NULL) ## single, separate colors -#' +#' #' ## further variations #' tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) #' tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) -#' +#' #' tinytheme() ## reset -#' +#' +#' @importFrom stats time #' @export tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), ylab = "", ...) { ## basic object properties From 4fd44ec2d6e346291a6e7e12c121e352d5cb4642 Mon Sep 17 00:00:00 2001 From: Achim Zeileis Date: Sun, 22 Mar 2026 17:52:35 +0100 Subject: [PATCH 04/22] tests for tinyplot.ts --- .../_tinysnapshot/ts-multivariate-by-free.svg | 260 ++++++++++++++++++ .../_tinysnapshot/ts-multivariate-by-same.svg | 242 ++++++++++++++++ .../_tinysnapshot/ts-multivariate-column.svg | 228 +++++++++++++++ .../_tinysnapshot/ts-multivariate-free.svg | 242 ++++++++++++++++ .../_tinysnapshot/ts-multivariate-same.svg | 224 +++++++++++++++ .../_tinysnapshot/ts-multivariate-single.svg | 87 ++++++ inst/tinytest/_tinysnapshot/ts-univariate.svg | 65 +++++ inst/tinytest/test-ts.R | 48 ++++ 8 files changed, 1396 insertions(+) create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-column.svg create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-free.svg create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-same.svg create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-single.svg create mode 100644 inst/tinytest/_tinysnapshot/ts-univariate.svg create mode 100644 inst/tinytest/test-ts.R diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg new file mode 100644 index 000000000..7f7610622 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg @@ -0,0 +1,260 @@ + + + + + + + + + + + + + + + + + + +Series +Series 1 +Series 2 +Series 3 +Series 4 +Series 5 + + + + + + + +Time + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +-2 +0 +2 +4 + +Series 1 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + +-10 +-8 +-6 +-4 +-2 +0 + +Series 2 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + +-2 +0 +2 +4 +6 +8 + +Series 3 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +-2 +0 +2 +4 + +Series 4 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + + +-6 +-4 +-2 +0 +2 +4 +6 + +Series 5 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg new file mode 100644 index 000000000..252404711 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + + + + + + +Series +Series 1 +Series 2 +Series 3 +Series 4 +Series 5 + + + + + + + +Time + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 1 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 2 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 3 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 4 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 5 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg new file mode 100644 index 000000000..87b988f39 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg @@ -0,0 +1,228 @@ + + + + + + + + + + + + + +Time + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +0 +4 + +Series 1 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + +-10 +-4 +0 + +Series 2 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + +-2 +2 +6 + +Series 3 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +0 +4 + +Series 4 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + + +-6 +0 +4 + +Series 5 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg new file mode 100644 index 000000000..88b7b6228 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg @@ -0,0 +1,242 @@ + + + + + + + + + + + + + +Time + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +-2 +0 +2 +4 + +Series 1 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + +-10 +-8 +-6 +-4 +-2 +0 + +Series 2 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + +-2 +0 +2 +4 +6 +8 + +Series 3 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +-2 +0 +2 +4 + +Series 4 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + + +-6 +-4 +-2 +0 +2 +4 +6 + +Series 5 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg new file mode 100644 index 000000000..b70592c3d --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg @@ -0,0 +1,224 @@ + + + + + + + + + + + + + +Time + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 1 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 2 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 3 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 4 + + + + + + + + + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + +Series 5 + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg new file mode 100644 index 000000000..6bc4d24ce --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg @@ -0,0 +1,87 @@ + + + + + + + + + + + + + + + + + + +Series +Series 1 +Series 2 +Series 3 +Series 4 +Series 5 + + + + + + + +Time + + + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/ts-univariate.svg b/inst/tinytest/_tinysnapshot/ts-univariate.svg new file mode 100644 index 000000000..1266463e6 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-univariate.svg @@ -0,0 +1,65 @@ + + + + + + + + + + + + + +Time + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + +-4 +-2 +0 +2 +4 + + + + + + + + + + + + diff --git a/inst/tinytest/test-ts.R b/inst/tinytest/test-ts.R new file mode 100644 index 000000000..399437455 --- /dev/null +++ b/inst/tinytest/test-ts.R @@ -0,0 +1,48 @@ +source("helpers.R") +using("tinysnapshot") + +## five random walks +set.seed(0) +x = c(0, rnorm(100)) |> + cumsum() |> + replicate(n = 5) |> + ts(start = 0) + +## univariate + +f = function() { + tinyplot(x[, 1]) +} +expect_snapshot_plot(f, label = "ts-univariate") + +## multivariate + +f = function() { + tinyplot(x) +} +expect_snapshot_plot(f, label = "ts-multivariate-free") + +f = function() { + tinyplot(x, facet.args = NULL) +} +expect_snapshot_plot(f, label = "ts-multivariate-same") + +f = function() { + tinyplot(x, facet = "by") +} +expect_snapshot_plot(f, label = "ts-multivariate-by-free") + +f = function() { + tinyplot(x, facet = "by", facet.args = NULL) +} +expect_snapshot_plot(f, label = "ts-multivariate-by-same") + +f = function() { + tinyplot(x, facet = NULL) +} +expect_snapshot_plot(f, label = "ts-multivariate-single") + +f = function() { + tinyplot(x, facet.args = list(free = TRUE, ncol = 1)) +} +expect_snapshot_plot(f, label = "ts-multivariate-column") From fe908c219c0a7e1c01e25523840be7b82b622a48 Mon Sep 17 00:00:00 2001 From: Achim Zeileis Date: Sun, 22 Mar 2026 17:56:19 +0100 Subject: [PATCH 05/22] NEWS item for tinyplot.ts --- NEWS.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/NEWS.md b/NEWS.md index 49a7d2297..c173597c9 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,13 @@ where the formatting is also better._ ## Development version +### New features + +- New dedicated `tinyplot()` method for `ts` time series. Internally, this sets + up a long data frame with columns `Time`, `Value`, and `Series` and then calls + the formula method with different possible specifications for the `by` and `facet` + variables. (#558 @zeileis) + ### Aesthetic changes - The legend plot characters for the `"pointrange"` and `"errorbar"` types now From 94bac616075f391deff6a239acdb43e189089f27 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 16:45:40 -0700 Subject: [PATCH 06/22] snapshot updates --- .../_tinysnapshot/ts-multivariate-by-free.svg | 12 ++++++------ .../_tinysnapshot/ts-multivariate-by-same.svg | 14 +++++++------- .../_tinysnapshot/ts-multivariate-column.svg | 10 +++++----- .../_tinysnapshot/ts-multivariate-free.svg | 10 +++++----- .../_tinysnapshot/ts-multivariate-same.svg | 10 +++++----- .../_tinysnapshot/ts-multivariate-single.svg | 2 +- 6 files changed, 29 insertions(+), 29 deletions(-) diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg index 7f7610622..d7394fe04 100644 --- a/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-by-free.svg @@ -31,7 +31,7 @@ -Series +Series Series 1 Series 2 Series 3 @@ -79,7 +79,7 @@ 2 4 -Series 1 +Series 1 @@ -117,7 +117,7 @@ -2 0 -Series 2 +Series 2 @@ -155,7 +155,7 @@ 6 8 -Series 3 +Series 3 @@ -191,7 +191,7 @@ 2 4 -Series 4 +Series 4 @@ -231,7 +231,7 @@ 4 6 -Series 5 +Series 5 diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg index 252404711..9e2b98c6c 100644 --- a/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-by-same.svg @@ -31,7 +31,7 @@ -Series +Series Series 1 Series 2 Series 3 @@ -77,7 +77,7 @@ 0 5 -Series 1 +Series 1 @@ -111,7 +111,7 @@ 0 5 -Series 2 +Series 2 @@ -145,7 +145,7 @@ 0 5 -Series 3 +Series 3 @@ -179,7 +179,7 @@ 0 5 -Series 4 +Series 4 @@ -213,7 +213,7 @@ 0 5 -Series 5 +Series 5 @@ -223,7 +223,7 @@ - + diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg index 87b988f39..f96bb8ad9 100644 --- a/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-column.svg @@ -59,7 +59,7 @@ 0 4 -Series 1 +Series 1 @@ -94,7 +94,7 @@ -4 0 -Series 2 +Series 2 @@ -129,7 +129,7 @@ 2 6 -Series 3 +Series 3 @@ -163,7 +163,7 @@ 0 4 -Series 4 +Series 4 @@ -199,7 +199,7 @@ 0 4 -Series 5 +Series 5 diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg index 88b7b6228..e78e4aae1 100644 --- a/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-free.svg @@ -61,7 +61,7 @@ 2 4 -Series 1 +Series 1 @@ -99,7 +99,7 @@ -2 0 -Series 2 +Series 2 @@ -137,7 +137,7 @@ 6 8 -Series 3 +Series 3 @@ -173,7 +173,7 @@ 2 4 -Series 4 +Series 4 @@ -213,7 +213,7 @@ 4 6 -Series 5 +Series 5 diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg index b70592c3d..70456390d 100644 --- a/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-same.svg @@ -59,7 +59,7 @@ 0 5 -Series 1 +Series 1 @@ -93,7 +93,7 @@ 0 5 -Series 2 +Series 2 @@ -127,7 +127,7 @@ 0 5 -Series 3 +Series 3 @@ -161,7 +161,7 @@ 0 5 -Series 4 +Series 4 @@ -195,7 +195,7 @@ 0 5 -Series 5 +Series 5 diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg index 6bc4d24ce..09ddd416b 100644 --- a/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-single.svg @@ -31,7 +31,7 @@ -Series +Series Series 1 Series 2 Series 3 From 4fba821dde73b4e6a10b7d0c73d3413ed5d074a8 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 17:11:13 -0700 Subject: [PATCH 07/22] NOT_CRAN env var for tinytest CI --- .github/workflows/R-CMD-check.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 0fd35af76..d839dacf2 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -29,6 +29,7 @@ jobs: env: GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }} R_KEEP_PKG_SOURCE: yes + NOT_CRAN: true steps: - uses: actions/checkout@v6 From 1e280000d06b9e84c7dc8eb3f25f4d1c8ff2c026 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 18:24:54 -0700 Subject: [PATCH 08/22] histogram and other distribution type exceptions --- R/tinyplot.ts.R | 57 +++++++++++++++++++++++++++++++++++++++------- man/tinyplot.ts.Rd | 12 ++++++++++ 2 files changed, 61 insertions(+), 8 deletions(-) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index 7576049a7..bb42c57f2 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -10,11 +10,19 @@ #' `Value ~ Time` or `Value ~ Time | Series`. See the `facet` argument #' description for more details and the examples for some illustrations. #' +#' An exception is made if the user explicitly supplies a distribution `type` +#' argument (i.e, one of `"histogram"`, `"density"`, `"boxplot"`, `"violin"`, +#' `"qq"`, `"ridge"`, or `"rug"`). These summarize the series values and +#' ignore the time index, so they are visualized with the one-sided +#' formula `~ Value` (or `~ Value | Series` for multivariate series). This +#' preserves base-R-compatible behaviour such as +#' `tinyplot(Nile, type = "histogram")`. +#' #' @param x an object of class `"ts"`. #' @param facet specification of `facet` for `tinyplot.formula`. The #' default in the `tinyplot` method is to use `facet = NULL` for univariate #' series and `facet = ~ Series` (equivalent to `facet = "by"`) for multivariate series. -#' @param type,facet.args,ylab,... further arguments passed to `tinyplot`. +#' @param type,facet.args,ylab,... further arguments passed to `tinyplot`. #' #' @examples #' tinytheme("clean2") @@ -22,6 +30,10 @@ #' ## univariate series #' tinyplot(Nile) #' +#' # exception: explcitly passing a distribution type on a univariate time +#' # series triggers the corresponding transformation +#' tinyplot(Nile, type = "histogram") +#' #' ## multivariate #' tinyplot(EuStockMarkets) ## multiple, same color, free scales #' tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale @@ -44,6 +56,8 @@ tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), yla if (k > 1L) lab = paste(lab, 1L:k, sep = ".") if (!is.null(colnames(x))) lab = colnames(x) + single = k == 1L + ## convert to long data.frame df = data.frame( Time = rep.int(as.numeric(time(x)), k), @@ -51,20 +65,47 @@ tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), yla Series = factor(rep(1L:k, each = n), labels = lab) ) + ## Distribution types summarize the series *values* and ignore the time index, + ## so they dispatch with a one-sided formula (`~ Value`, or `~ Value | Series` + ## when multivariate) rather than `Value ~ Time`, and skip the time-series + ## `ylab` default so tinyplot's own label (e.g. "Frequency") shows. This + ## preserves base-R-compatible behaviour like `tinyplot(Nile, type = "histogram")`. + dist_types = c("histogram", "hist", "density", "boxplot", "box", + "violin", "qq", "ridge", "rug") + ## normalize to a type name to catch both the string ("histogram") and the + ## type object (`type_histogram()`, whose `$name` is the canonical "histogram") + type_name = if (inherits(type, "tinyplot_type")) { + type[["name"]] + } else if (is.character(type) && length(type) == 1L) { + type + } else { + NA_character_ + } + is_dist = !is.na(type_name) && type_name %in% dist_types + ## default for facet - single = k == 1L if(missing(facet)) { auto = TRUE - facet = if(single) NULL else ~ Series + facet = if(single || is_dist) NULL else ~ Series } else { auto = FALSE } if (is.null(facet)) facet.args = NULL - - ## call tinyplot - if(single | (!is.null(facet) & auto)) { - tinyplot(Value ~ Time, data = df, facet = facet, facet.args = facet.args, type = type, ylab = ylab, ...) + + ## dispatch formula and axis labels + xlab = NULL + if (is_dist) { + fml = if (single) ~ Value else ~ Value | Series + if (single) xlab = lab + ## use tinyplot's own ylab default (e.g. "Frequency") unless caller set one + if (missing(ylab)) ylab = NULL + } else if (single || (!is.null(facet) && auto)) { + fml = Value ~ Time } else { - tinyplot(Value ~ Time | Series, data = df, facet = facet, facet.args = facet.args, type = type, ylab = ylab, ...) + fml = Value ~ Time | Series } + + ## call tinyplot + tinyplot(fml, data = df, type = type, facet = facet, facet.args = facet.args, + xlab = xlab, ylab = ylab, ...) } diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd index 752897f86..93072f5c9 100644 --- a/man/tinyplot.ts.Rd +++ b/man/tinyplot.ts.Rd @@ -26,6 +26,14 @@ and \code{Series} (factor with column labels). Depending on the settings of \code{facet} this data frame is visualized either with the formula \code{Value ~ Time} or \code{Value ~ Time | Series}. See the \code{facet} argument description for more details and the examples for some illustrations. + +An exception is made if the user explicitly supplies a distribution \code{type} +argument (i.e, one of \code{"histogram"}, \code{"density"}, \code{"boxplot"}, \code{"violin"}, +\code{"qq"}, \code{"ridge"}, or \code{"rug"}). These summarize the series values and +ignore the time index, so they are visualized with the one-sided +formula \code{~ Value} (or \code{~ Value | Series} for multivariate series). This +preserves base-R-compatible behaviour such as +\code{tinyplot(Nile, type = "histogram")}. } \examples{ tinytheme("clean2") @@ -33,6 +41,10 @@ tinytheme("clean2") ## univariate series tinyplot(Nile) +# exception: explcitly passing a distribution type on a univariate time +# series triggers the corresponding transformation +tinyplot(Nile, type = "histogram") + ## multivariate tinyplot(EuStockMarkets) ## multiple, same color, free scales tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale From d74543544e5c2a52d25f224ea5d2b69d6aedbbe1 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 19:52:53 -0700 Subject: [PATCH 09/22] direct labs example --- R/tinyplot.ts.R | 5 +++-- man/tinyplot.ts.Rd | 5 +++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index bb42c57f2..d13936cad 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -30,8 +30,8 @@ #' ## univariate series #' tinyplot(Nile) #' -#' # exception: explcitly passing a distribution type on a univariate time -#' # series triggers the corresponding transformation +#' # exception: expicitly passing a distribution type on a univariate series +#' # still triggers the corresponding transformation #' tinyplot(Nile, type = "histogram") #' #' ## multivariate @@ -43,6 +43,7 @@ #' ## further variations #' tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) #' tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) +#' tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) #' #' tinytheme() ## reset #' diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd index 93072f5c9..218ccbd5b 100644 --- a/man/tinyplot.ts.Rd +++ b/man/tinyplot.ts.Rd @@ -41,8 +41,8 @@ tinytheme("clean2") ## univariate series tinyplot(Nile) -# exception: explcitly passing a distribution type on a univariate time -# series triggers the corresponding transformation +# exception: expicitly passing a distribution type on a univariate series +# still triggers the corresponding transformation tinyplot(Nile, type = "histogram") ## multivariate @@ -54,6 +54,7 @@ tinyplot(EuStockMarkets, facet = NULL) ## single, separate colors ## further variations tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) +tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) tinytheme() ## reset From de9529e499aa31c802ee4331e887a2ff0323380c Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 21:12:15 -0700 Subject: [PATCH 10/22] news --- NEWS.md | 87 +++++++++++++++++++++++++--------------------- altdoc/pkgdown.yml | 2 +- 2 files changed, 49 insertions(+), 40 deletions(-) diff --git a/NEWS.md b/NEWS.md index 088a56ac4..257c88430 100644 --- a/NEWS.md +++ b/NEWS.md @@ -148,7 +148,9 @@ Theme fixes: subtitle, and legend stack correctly above the plot region with proper spacing. (#605) -### New plot types +### New features + +#### New plot types - `type_chull()` (equivalently, `type = "chull"`) for drawing convex hulls around grouped points. Uses `grDevices::chull()` under the hood and delegates @@ -158,10 +160,10 @@ Theme fixes: ellipses around grouped points. Like `type_chull`, works well as a filled layer, e.g. `plt_add(type = "ellipse", fill = 0.2)`. (#610 @grantmcdermott) -### Other new features +#### New `tinyplot.*` methods -- A new top-level `tinypairs()` function, together with a dedicated - `tinyplot.data.frame()` method now supports direct plotting of data frames, +- A top-level `tinypairs()` function, together with a dedicated + `tinyplot.data.frame()` method, now supports direct plotting of data frames, with or without a formula. Combining with a formula is mostly useful insofar as it facilitates piping, e.g. @@ -174,7 +176,20 @@ Theme fixes: variables will yield a `pairs()`-style grid of all variable combinations. Thanks to @mthulin for the suggestion and original implementation idea. (#613, #640 @zeileis @grantmcdermott) -- New top-level `tinyplot()`/`plt()` arguments: +- New dedicated `tinyplot.ts()` method for `ts` time series, e.g. + + ```r + plt(EuStockMarkets) + ``` + + Produces a line plot by default, although users can override by passing an + explicit `type` argument. Similarly, multivariate series are faceted by + default, but users can also override to obtain, say, a single frame with + direct labels. (#558 @zeileis) + +#### Other new features + +- New and updated top-level `tinyplot()`/`plt()` arguments: - `cap = ` for adding a caption to your plots. Captions are drawn at the bottom of the plot and are best paired with dynamic themes (since separation from `sub` is guaranteed). Appearance is customizable via @@ -211,33 +226,34 @@ Theme fixes: ``` The `labels` arg is silently ignored for non-text types. (#639 @grantmcdermott) -- The `grid` argument (and `tpar("grid")`) now accepts character strings to - control axis-specific grids at different resolutions. Uppercase letters - (`"X"`, `"Y"`, `"XY"`) draw grid lines at the standard tick positions, while - lowercase letters (`"x"`, `"y"`, `"xy"`) draw a finer grid with additional - lines at the midpoints between ticks. Thanks to @zeileis for the suggestion. - (#578 @grantmcdermott) -- Facet formulas now support `1` as a convenience syntax for single row or - column arrangements. (#562 @zeileis) - - `plt(..., facet = z ~ 1)` <-> `plt(..., facet = ~z, facet.args = list(ncol = 1))` - - `plt(..., facet = 1 ~ z)` <-> `plt(..., facet = ~z, facet.args = list(nrow = 1))`. -- `type_barplot()` gains an `offset` argument for shifting bar baselines away - from zero. (#611, #615 @grantmcdermott @zeileis) - - If the offset is an unnamed scalar or numeric vector, it shifts the bars - positionally by the given values. Useful for creating waterfall plots and - floating bars. - - If the offset is a character or named numeric vector, it instead "sets - aside" the named level(s) of the `by` group, pulling them out of the stack - and drawing them as standalone bars. This is useful for Likert plots, where - you want to show a neutral categories (e.g., "Unsure") apart from the - diverging stack. Thanks to @strengejacke for the suggestion. -- `type_text()` gains two new arguments: - - a `labeller` argument that is passed to `tinylabel()` for formatting the - text labels. (#620 @grantmcdermott) - - a `repel` argument that automatically nudges overlapping text labels apart. - One limitation is that the repulsion logic operates with groups. So there - may still be some overlapping text for for grouped data. - (#621 @grantmcdermott) + - The `grid` argument (and `tpar("grid")`) now accepts character strings to + control axis-specific grids at different resolutions. Uppercase letters + (`"X"`, `"Y"`, `"XY"`) draw grid lines at the standard tick positions, while + lowercase letters (`"x"`, `"y"`, `"xy"`) draw a finer grid with additional + lines at the midpoints between ticks. Thanks to @zeileis for the suggestion. + (#578 @grantmcdermott) + - Facet formulas now support `1` as a convenience syntax for single row or + column arrangements. (#562 @zeileis) + - `plt(..., facet = z ~ 1)` <-> `plt(..., facet = ~z, facet.args = list(ncol = 1))` + - `plt(..., facet = 1 ~ z)` <-> `plt(..., facet = ~z, facet.args = list(nrow = 1))`. +- Type-specific updates: + - `type_barplot()` gains an `offset` argument for shifting bar baselines away + from zero. (#611, #615 @grantmcdermott @zeileis) + - If the offset is an unnamed scalar or numeric vector, it shifts the bars + positionally by the given values. Useful for creating waterfall plots and + floating bars. + - If the offset is a character or named numeric vector, it instead "sets + aside" the named level(s) of the `by` group, pulling them out of the stack + and drawing them as standalone bars. This is useful for Likert plots, + where you want to show a neutral categories (e.g., "Unsure") apart from + the diverging stack. Thanks to @strengejacke for the suggestion. + - `type_text()` gains two new arguments: + - a `labeller` argument that is passed to `tinylabel()` for formatting the + text labels. (#620 @grantmcdermott) + - a `repel` argument that automatically nudges overlapping text labels + apart. One limitation is that the repulsion logic operates with groups. So + there may still be some overlapping text for for grouped data. + (#621 @grantmcdermott) ### Bug fixes @@ -283,13 +299,6 @@ Theme fixes: ## v0.6.1 -### New features - -- New dedicated `tinyplot()` method for `ts` time series. Internally, this sets - up a long data frame with columns `Time`, `Value`, and `Series` and then calls - the formula method with different possible specifications for the `by` and `facet` - variables. (#558 @zeileis) - ### Aesthetic changes - The legend plot characters for the `"pointrange"` and `"errorbar"` types now diff --git a/altdoc/pkgdown.yml b/altdoc/pkgdown.yml index c535a9f5f..c862fc831 100644 --- a/altdoc/pkgdown.yml +++ b/altdoc/pkgdown.yml @@ -2,7 +2,7 @@ altdoc: 0.7.2 pandoc: '3.10' pkgdown: 2.1.3 pkgdown_sha: ~ -last_built: 2026-06-22T18:44:13+0000 +last_built: 2026-06-23T04:10:24+0000 urls: reference: https://grantmcdermott.com/tinyplot/man article: https://grantmcdermott.com/tinyplot/vignettes From ba7a58b24a9af4c5d7a2922c2d39448e53fee970 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 21:14:21 -0700 Subject: [PATCH 11/22] news tweak --- NEWS.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/NEWS.md b/NEWS.md index 257c88430..55f88d228 100644 --- a/NEWS.md +++ b/NEWS.md @@ -254,6 +254,9 @@ Theme fixes: apart. One limitation is that the repulsion logic operates with groups. So there may still be some overlapping text for for grouped data. (#621 @grantmcdermott) + - Model-fit and various distribution types gain a `weights` argument; although + this is best provided from the top-level `tinyplot()`/`plt()` call. See + above. ### Bug fixes From e7603df42375a8cc0cda6ee1e5c0c447883b2e99 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 21:17:48 -0700 Subject: [PATCH 12/22] gallery update --- vignettes/gallery_figs/line-eustockmarkets.R | 22 ++++++-------------- 1 file changed, 6 insertions(+), 16 deletions(-) diff --git a/vignettes/gallery_figs/line-eustockmarkets.R b/vignettes/gallery_figs/line-eustockmarkets.R index a71b8a168..dacb4b70d 100644 --- a/vignettes/gallery_figs/line-eustockmarkets.R +++ b/vignettes/gallery_figs/line-eustockmarkets.R @@ -1,21 +1,11 @@ -## note: replace with tinyplot.ts method once #558 is merged - data("EuStockMarkets", package = "datasets") -eu = data.frame( - time = rep(time(EuStockMarkets), ncol(EuStockMarkets)), - market = rep(colnames(EuStockMarkets), each = nrow(EuStockMarkets)), - value = as.numeric(EuStockMarkets) -) - library("tinyplot") + +## demos the tinyplot.ts method (#558) tinyplot( - value ~ time | market, - data = eu, - facet = "by", legend = FALSE, - type = "l", - theme = "clean2", - main = "EU stock markets performance", - xlab = NA, ylab = NA, - yaxl = "," + EuStockMarkets, + yaxl = ",", + main = "EU stock markets performance", + theme = "clean2" ) From c04e0458b6235f6079c9760a41c8be6b137e5691 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Mon, 22 Jun 2026 21:20:02 -0700 Subject: [PATCH 13/22] test website --- altdoc/pkgdown.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/altdoc/pkgdown.yml b/altdoc/pkgdown.yml index c862fc831..cf4a294e1 100644 --- a/altdoc/pkgdown.yml +++ b/altdoc/pkgdown.yml @@ -2,7 +2,7 @@ altdoc: 0.7.2 pandoc: '3.10' pkgdown: 2.1.3 pkgdown_sha: ~ -last_built: 2026-06-23T04:10:24+0000 +last_built: 2026-06-23T04:17:55+0000 urls: reference: https://grantmcdermott.com/tinyplot/man article: https://grantmcdermott.com/tinyplot/vignettes From 9930a5d70434d663055c239c2b29c04d5417a29f Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 09:19:46 -0700 Subject: [PATCH 14/22] ci: try to upload review artifact if failure --- .github/workflows/R-CMD-check.yaml | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index d839dacf2..30749357c 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -42,3 +42,14 @@ jobs: - name: Test run: ./run.sh run_tests + + - name: Upload snapshot review (on failure) + if: failure() + uses: actions/upload-artifact@v4 + with: + name: tinysnapshot-review-${{ matrix.name }} + path: | + *.Rcheck/tests/tinytest/_tinysnapshot_review/ + *.Rcheck/00check.log + if-no-files-found: ignore + retention-days: 7 From d148536f95c0fbccc543bcf7f8d48fda6ece9983 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 09:37:31 -0700 Subject: [PATCH 15/22] ci: use glob for review dir --- .github/workflows/R-CMD-check.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/R-CMD-check.yaml b/.github/workflows/R-CMD-check.yaml index 30749357c..c7c2fcf59 100644 --- a/.github/workflows/R-CMD-check.yaml +++ b/.github/workflows/R-CMD-check.yaml @@ -49,7 +49,7 @@ jobs: with: name: tinysnapshot-review-${{ matrix.name }} path: | - *.Rcheck/tests/tinytest/_tinysnapshot_review/ + *.Rcheck/**/_tinysnapshot_review/** *.Rcheck/00check.log if-no-files-found: ignore retention-days: 7 From 7f53e8fd07c377fb8034ce010ced557df377e2a5 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 10:03:03 -0700 Subject: [PATCH 16/22] drop false positive and add direct legend version --- .../ts-multivariate-by-direct.svg | 74 +++++++++++++++++++ inst/tinytest/test-ts.R | 15 ++-- 2 files changed, 83 insertions(+), 6 deletions(-) create mode 100644 inst/tinytest/_tinysnapshot/ts-multivariate-by-direct.svg diff --git a/inst/tinytest/_tinysnapshot/ts-multivariate-by-direct.svg b/inst/tinytest/_tinysnapshot/ts-multivariate-by-direct.svg new file mode 100644 index 000000000..335ce941c --- /dev/null +++ b/inst/tinytest/_tinysnapshot/ts-multivariate-by-direct.svg @@ -0,0 +1,74 @@ + + + + + + + + + + + + + +Time + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + +-10 +-5 +0 +5 + + + + + + + + + + + + + + + +Series 1 +Series 2 +Series 3 +Series 4 +Series 5 + + + diff --git a/inst/tinytest/test-ts.R b/inst/tinytest/test-ts.R index 399437455..ee1c9f974 100644 --- a/inst/tinytest/test-ts.R +++ b/inst/tinytest/test-ts.R @@ -3,10 +3,7 @@ using("tinysnapshot") ## five random walks set.seed(0) -x = c(0, rnorm(100)) |> - cumsum() |> - replicate(n = 5) |> - ts(start = 0) +x = ts(replicate(cumsum(c(0, rnorm(100))), n = 5), start = 0) ## univariate @@ -32,10 +29,16 @@ f = function() { } expect_snapshot_plot(f, label = "ts-multivariate-by-free") +## Currently triggers a false positive on the devcontainer +# f = function() { +# tinyplot(x, facet = "by", facet.args = NULL) +# } +# expect_snapshot_plot(f, label = "ts-multivariate-by-same") + f = function() { - tinyplot(x, facet = "by", facet.args = NULL) + tinyplot(x, facet = NULL, legend = list("direct", repel = TRUE)) } -expect_snapshot_plot(f, label = "ts-multivariate-by-same") +expect_snapshot_plot(f, label = "ts-multivariate-by-direct") f = function() { tinyplot(x, facet = NULL) From e0acb01b5b7304f431f9d2d9781a5196c993d163 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 10:39:43 -0700 Subject: [PATCH 17/22] allow xlab override and tweak examples --- R/tinyplot.ts.R | 30 ++++++++++++++++-------------- man/tinyplot.ts.Rd | 35 +++++++++++++++++++++++------------ 2 files changed, 39 insertions(+), 26 deletions(-) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index d13936cad..9680840b9 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -8,7 +8,7 @@ #' and `Series` (factor with column labels). Depending on the settings #' of `facet` this data frame is visualized either with the formula #' `Value ~ Time` or `Value ~ Time | Series`. See the `facet` argument -#' description for more details and the examples for some illustrations. +#' description for more details and the Examples below for some illustrations. #' #' An exception is made if the user explicitly supplies a distribution `type` #' argument (i.e, one of `"histogram"`, `"density"`, `"boxplot"`, `"violin"`, @@ -21,12 +21,11 @@ #' @param x an object of class `"ts"`. #' @param facet specification of `facet` for `tinyplot.formula`. The #' default in the `tinyplot` method is to use `facet = NULL` for univariate -#' series and `facet = ~ Series` (equivalent to `facet = "by"`) for multivariate series. -#' @param type,facet.args,ylab,... further arguments passed to `tinyplot`. +#' series and `facet = ~ Series` (equivalent to `facet = "by"`) for +#' multivariate series. +#' @param type,facet.args,xlab,ylab,... further arguments passed to `tinyplot`. #' #' @examples -#' tinytheme("clean2") -#' #' ## univariate series #' tinyplot(Nile) #' @@ -34,22 +33,26 @@ #' # still triggers the corresponding transformation #' tinyplot(Nile, type = "histogram") #' -#' ## multivariate -#' tinyplot(EuStockMarkets) ## multiple, same color, free scales -#' tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale -#' tinyplot(EuStockMarkets, facet = "by") ## multiple, separate colors, free scales -#' tinyplot(EuStockMarkets, facet = NULL) ## single, separate colors +#' ## multivariate series (generally, these also look better with a theme) +#' tinytheme("clean2") +#' tinyplot(EuStockMarkets) ## faceted, free scales, same color +#' tinyplot(EuStockMarkets, facet.args = NULL) ## faceted, same scale, same color +#' tinyplot(EuStockMarkets, facet = "by") ## faceted, free scales, diff colors +#' tinyplot(EuStockMarkets, facet = NULL) ## single frame, diff colors #' #' ## further variations +#' tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) #' tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) #' tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) -#' tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) +#' +#' ## pass other tinyplot args through `...` for additional customization +#' tinyplot(EuStockMarkets, main = "European stock indices", xlab = NA, yaxl = ",") #' #' tinytheme() ## reset #' #' @importFrom stats time #' @export -tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), ylab = "", ...) { +tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), xlab = NULL, ylab = NA, ...) { ## basic object properties n = NROW(x) k = NCOL(x) @@ -94,10 +97,9 @@ tinyplot.ts = function(x, facet, type = "l", facet.args = list(free = TRUE), yla if (is.null(facet)) facet.args = NULL ## dispatch formula and axis labels - xlab = NULL if (is_dist) { fml = if (single) ~ Value else ~ Value | Series - if (single) xlab = lab + if (single && is.null(xlab)) xlab = lab ## use tinyplot's own ylab default (e.g. "Frequency") unless caller set one if (missing(ylab)) ylab = NULL } else if (single || (!is.null(facet) && auto)) { diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd index 218ccbd5b..677c4a768 100644 --- a/man/tinyplot.ts.Rd +++ b/man/tinyplot.ts.Rd @@ -4,16 +4,25 @@ \alias{tinyplot.ts} \title{tinyplot Method for Plotting ts Objects (Time Series)} \usage{ -\method{tinyplot}{ts}(x, facet, type = "l", facet.args = list(free = TRUE), ylab = "", ...) +\method{tinyplot}{ts}( + x, + facet, + type = "l", + facet.args = list(free = TRUE), + xlab = NULL, + ylab = NA, + ... +) } \arguments{ \item{x}{an object of class \code{"ts"}.} \item{facet}{specification of \code{facet} for \code{tinyplot.formula}. The default in the \code{tinyplot} method is to use \code{facet = NULL} for univariate -series and \code{facet = ~ Series} (equivalent to \code{facet = "by"}) for multivariate series.} +series and \code{facet = ~ Series} (equivalent to \code{facet = "by"}) for +multivariate series.} -\item{type, facet.args, ylab, ...}{further arguments passed to \code{tinyplot}.} +\item{type, facet.args, xlab, ylab, ...}{further arguments passed to \code{tinyplot}.} } \description{ Convenience interface for visualizing ts objects @@ -25,7 +34,7 @@ data frame with columns \code{Time} (time index), \code{Value} (observations), and \code{Series} (factor with column labels). Depending on the settings of \code{facet} this data frame is visualized either with the formula \code{Value ~ Time} or \code{Value ~ Time | Series}. See the \code{facet} argument -description for more details and the examples for some illustrations. +description for more details and the Examples below for some illustrations. An exception is made if the user explicitly supplies a distribution \code{type} argument (i.e, one of \code{"histogram"}, \code{"density"}, \code{"boxplot"}, \code{"violin"}, @@ -36,8 +45,6 @@ preserves base-R-compatible behaviour such as \code{tinyplot(Nile, type = "histogram")}. } \examples{ -tinytheme("clean2") - ## univariate series tinyplot(Nile) @@ -45,16 +52,20 @@ tinyplot(Nile) # still triggers the corresponding transformation tinyplot(Nile, type = "histogram") -## multivariate -tinyplot(EuStockMarkets) ## multiple, same color, free scales -tinyplot(EuStockMarkets, facet.args = NULL) ## multiple, same color, same scale -tinyplot(EuStockMarkets, facet = "by") ## multiple, separate colors, free scales -tinyplot(EuStockMarkets, facet = NULL) ## single, separate colors +## multivariate series (generally, these also look better with a theme) +tinytheme("clean2") +tinyplot(EuStockMarkets) ## faceted, free scales, same color +tinyplot(EuStockMarkets, facet.args = NULL) ## faceted, same scale, same color +tinyplot(EuStockMarkets, facet = "by") ## faceted, free scales, diff colors +tinyplot(EuStockMarkets, facet = NULL) ## single frame, diff colors ## further variations +tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) -tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) + +## pass other tinyplot args through `...` for additional customization +tinyplot(EuStockMarkets, main = "European stock indices", xlab = NA, yaxl = ",") tinytheme() ## reset From f5a1cd1ade190299320497555385ed5b90ad5ab7 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 10:43:59 -0700 Subject: [PATCH 18/22] update website --- altdoc/pkgdown.yml | 2 +- altdoc/quarto_website.yml | 8 ++------ 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/altdoc/pkgdown.yml b/altdoc/pkgdown.yml index cf4a294e1..b5bcb026a 100644 --- a/altdoc/pkgdown.yml +++ b/altdoc/pkgdown.yml @@ -2,7 +2,7 @@ altdoc: 0.7.2 pandoc: '3.10' pkgdown: 2.1.3 pkgdown_sha: ~ -last_built: 2026-06-23T04:17:55+0000 +last_built: 2026-06-23T17:42:29+0000 urls: reference: https://grantmcdermott.com/tinyplot/man article: https://grantmcdermott.com/tinyplot/vignettes diff --git a/altdoc/quarto_website.yml b/altdoc/quarto_website.yml index 8e4e1a585..c6ce09b21 100644 --- a/altdoc/quarto_website.yml +++ b/altdoc/quarto_website.yml @@ -62,12 +62,6 @@ website: file: man/tinyplot.qmd - text: tinyplot_add file: man/tinyplot_add.qmd - - text: tinypairs - file: man/tinyplot.data.frame.qmd - # - section: "Methods" - # contents: - # - text: tinyplot.data.frame - # file: man/tinyplot.data.frame.qmd - section: "Types" contents: - section: Shapes @@ -166,6 +160,8 @@ website: contents: - text: tinyplot.data.frame file: man/tinyplot.data.frame.qmd + - text: tinyplot.ts + file: man/tinyplot.ts.qmd format: html: From 4d8762f568df74a18e2ab9af29077ec690cecc58 Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 11:37:13 -0700 Subject: [PATCH 19/22] add returns field to avoid R CMD check --as-cran NOTE --- R/tinyplot.data.frame.R | 2 ++ R/tinyplot.ts.R | 2 ++ man/tinyplot.data.frame.Rd | 3 +++ man/tinyplot.ts.Rd | 3 +++ 4 files changed, 10 insertions(+) diff --git a/R/tinyplot.data.frame.R b/R/tinyplot.data.frame.R index f8f86f115..1633a4714 100644 --- a/R/tinyplot.data.frame.R +++ b/R/tinyplot.data.frame.R @@ -37,6 +37,8 @@ #' to disambiguate from `frame.plot`. #' @param ... further arguments passed to `tinyplot`. #' +#' @returns No return value, called for the side effect of producing a plot. +#' #' @examples #' ## using tinyplot() with data frames #' tinyplot(cars) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index 9680840b9..509bb3d3c 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -25,6 +25,8 @@ #' multivariate series. #' @param type,facet.args,xlab,ylab,... further arguments passed to `tinyplot`. #' +#' @returns No return value, called for the side effect of producing a plot. +#' #' @examples #' ## univariate series #' tinyplot(Nile) diff --git a/man/tinyplot.data.frame.Rd b/man/tinyplot.data.frame.Rd index 41bd46c7c..933f471ec 100644 --- a/man/tinyplot.data.frame.Rd +++ b/man/tinyplot.data.frame.Rd @@ -36,6 +36,9 @@ to disambiguate from \code{frame.plot}.} \item{...}{further arguments passed to \code{tinyplot}.} } +\value{ +No return value, called for the side effect of producing a plot. +} \description{ Convenience interface for visualizing \code{\link[base]{data.frame}} objects with tinyplot. diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd index 677c4a768..bc6b54052 100644 --- a/man/tinyplot.ts.Rd +++ b/man/tinyplot.ts.Rd @@ -24,6 +24,9 @@ multivariate series.} \item{type, facet.args, xlab, ylab, ...}{further arguments passed to \code{tinyplot}.} } +\value{ +No return value, called for the side effect of producing a plot. +} \description{ Convenience interface for visualizing ts objects (time sereis with tinyplot. From 148d1d65b59831d7bb5a6fc9b0a68daa81b4551e Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 11:43:58 -0700 Subject: [PATCH 20/22] typos --- R/tinyplot.ts.R | 4 ++-- altdoc/pkgdown.yml | 2 +- man/tinyplot.ts.Rd | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index 509bb3d3c..6ccfcf479 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -1,7 +1,7 @@ #' tinyplot Method for Plotting ts Objects (Time Series) #' -#' @description Convenience interface for visualizing ts objects -#' (time sereis with tinyplot. +#' @description Convenience interface for visualizing \code{\link[stats]{ts}} +#' (time series) objects with tinyplot. #' #' @details Internally the time series object is converted to a long #' data frame with columns `Time` (time index), `Value` (observations), diff --git a/altdoc/pkgdown.yml b/altdoc/pkgdown.yml index b5bcb026a..ec4341743 100644 --- a/altdoc/pkgdown.yml +++ b/altdoc/pkgdown.yml @@ -2,7 +2,7 @@ altdoc: 0.7.2 pandoc: '3.10' pkgdown: 2.1.3 pkgdown_sha: ~ -last_built: 2026-06-23T17:42:29+0000 +last_built: 2026-06-23T18:43:03+0000 urls: reference: https://grantmcdermott.com/tinyplot/man article: https://grantmcdermott.com/tinyplot/vignettes diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd index bc6b54052..9b13106db 100644 --- a/man/tinyplot.ts.Rd +++ b/man/tinyplot.ts.Rd @@ -28,8 +28,8 @@ multivariate series.} No return value, called for the side effect of producing a plot. } \description{ -Convenience interface for visualizing ts objects -(time sereis with tinyplot. +Convenience interface for visualizing \code{\link[stats]{ts}} +(time series) objects with tinyplot. } \details{ Internally the time series object is converted to a long From e2d34abedfaf66aaf0e02d5d7c60cd86d3eb728f Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 11:48:20 -0700 Subject: [PATCH 21/22] news tweak --- NEWS.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/NEWS.md b/NEWS.md index 55f88d228..0bfdec0ee 100644 --- a/NEWS.md +++ b/NEWS.md @@ -185,7 +185,7 @@ Theme fixes: Produces a line plot by default, although users can override by passing an explicit `type` argument. Similarly, multivariate series are faceted by default, but users can also override to obtain, say, a single frame with - direct labels. (#558 @zeileis) + direct labels. (#558 @zeileis @grantmcdermott) #### Other new features From ef0b85ff7094222311f2908666750f4a44d9825b Mon Sep 17 00:00:00 2001 From: Grant McDermott Date: Tue, 23 Jun 2026 11:53:06 -0700 Subject: [PATCH 22/22] "area" example --- R/tinyplot.ts.R | 7 +++++-- altdoc/pkgdown.yml | 2 +- man/tinyplot.ts.Rd | 7 +++++-- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/R/tinyplot.ts.R b/R/tinyplot.ts.R index 6ccfcf479..b578dc8e0 100644 --- a/R/tinyplot.ts.R +++ b/R/tinyplot.ts.R @@ -47,8 +47,11 @@ #' tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) #' tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) #' -#' ## pass other tinyplot args through `...` for additional customization -#' tinyplot(EuStockMarkets, main = "European stock indices", xlab = NA, yaxl = ",") +#' ## pass additional tinyplot args through `...` for further customization +#' tinyplot(EuStockMarkets, +#' facet.args = NULL, +#' type = "area", xlab = NA, yaxl = ",", +#' main = "European stock indices") #' #' tinytheme() ## reset #' diff --git a/altdoc/pkgdown.yml b/altdoc/pkgdown.yml index ec4341743..0349cfa48 100644 --- a/altdoc/pkgdown.yml +++ b/altdoc/pkgdown.yml @@ -2,7 +2,7 @@ altdoc: 0.7.2 pandoc: '3.10' pkgdown: 2.1.3 pkgdown_sha: ~ -last_built: 2026-06-23T18:43:03+0000 +last_built: 2026-06-23T18:52:00+0000 urls: reference: https://grantmcdermott.com/tinyplot/man article: https://grantmcdermott.com/tinyplot/vignettes diff --git a/man/tinyplot.ts.Rd b/man/tinyplot.ts.Rd index 9b13106db..2efaed63f 100644 --- a/man/tinyplot.ts.Rd +++ b/man/tinyplot.ts.Rd @@ -67,8 +67,11 @@ tinyplot(EuStockMarkets, facet = NULL, legend = list("direct", repel = TRUE)) tinyplot(EuStockMarkets, facet = "by", facet.args = NULL) tinyplot(EuStockMarkets, facet.args = list(free = TRUE, ncol = 1)) -## pass other tinyplot args through `...` for additional customization -tinyplot(EuStockMarkets, main = "European stock indices", xlab = NA, yaxl = ",") +## pass additional tinyplot args through `...` for further customization +tinyplot(EuStockMarkets, + facet.args = NULL, + type = "area", xlab = NA, yaxl = ",", + main = "European stock indices") tinytheme() ## reset