diff --git a/NEWS.md b/NEWS.md index 8d38b9a5..30d41087 100644 --- a/NEWS.md +++ b/NEWS.md @@ -9,7 +9,10 @@ where the formatting is also better._ New features: - Support for additional plot types: - - `type = "n"`, i.e. empty plot. (#157 @grantmcdermott) + - `type = "n"`, i.e. empty plot. Since `type = "n"` implicitly assumes points, + which limits the type of legend that can be drawn alongside the empty plot, we + have also added a companion `empty` argument that can be used alongside any + plot type. (#157, #167 @grantmcdermott) - `type = "boxplot"`. Simultaneously enables `plt(numeric ~ factor)` support, first raised in #2, so that a boxplot is automatically plotted if a numeric is plotted against a factor. (#154 @grantmcdermott) diff --git a/R/tinyplot.R b/R/tinyplot.R index dab64744..062df1e8 100644 --- a/R/tinyplot.R +++ b/R/tinyplot.R @@ -72,12 +72,20 @@ #' for lines, "b" for both points and lines, "c" for empty points joined by #' lines, "o" for overplotted points and lines, "s" and "S" for stair steps, #' and "h" for histogram-like vertical lines. Specifying "n" produces an empty -#' plot over the extent of the data, but with no internal elements. +#' plot over the extent of the data, but with no internal elements (see also +#' the `empty` argument below). #' - Additional tinyplot types: "boxplot" for boxplots, "density" for #' densities, "polygon" or "polypath" for polygons, "pointrange" or"errorbar" #' for segment intervals, and "ribbon" or "area" for polygon intervals (where #' area plots are a special case of ribbon plots with `ymin` set to 0 and #' `ymax` set to `y`; see below). +#' @param empty logical indicating whether the interior plot region should be +#' left empty. The default is `FALSE`. Setting to `TRUE` has a similar effect +#' to invoking `type = "n"` above, except that any legend artifacts owing to a +#' particular plot type (e.g., lines for `type = "l"` or squares for +#' `type = "area"`) will still be drawn correctly alongside the empty plot. In +#' contrast,`type = "n"` implicitly assumes a scatterplot and so any legend +#' will only depict points. #' @param xmin,xmax,ymin,ymax minimum and maximum coordinates of relevant area #' or interval plot types. Only used when the `type` argument is one of #' "rect" or "segments" (where all four min-max coordinates are required), or @@ -250,7 +258,7 @@ #' graphics windows. #' @param height numeric giving the plot height in inches. Same considerations as #' `width` (above) apply, e.g. will default to `tpar("file.height")` if not -#' specified. +#' specified. #' @param ... other graphical parameters. See \code{\link[graphics]{par}} or #' the "Details" section of \code{\link[graphics]{plot}}. #' @@ -489,6 +497,7 @@ tinyplot.default = function( file = NULL, width = NULL, height = NULL, + empty = FALSE, ...) { dots = list(...) @@ -1372,7 +1381,7 @@ tinyplot.default = function( # empty plot flag empty_plot = FALSE - if (type=="n" || ((length(xx)==0) && !(type %in% c("rect","segments")))) { + if (isTRUE(empty) || type=="n" || ((length(xx)==0) && !(type %in% c("rect","segments")))) { empty_plot = TRUE } diff --git a/inst/tinytest/_tinysnapshot/type_l_empty.svg b/inst/tinytest/_tinysnapshot/type_l_empty.svg new file mode 100644 index 00000000..6dad484c --- /dev/null +++ b/inst/tinytest/_tinysnapshot/type_l_empty.svg @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + +Species +setosa +versicolor +virginica + + + + + + + +Petal.Length +Sepal.Length + + + + + + + + + + +1 +2 +3 +4 +5 +6 +7 + + + + + + + + + +4.5 +5.0 +5.5 +6.0 +6.5 +7.0 +7.5 +8.0 + + + diff --git a/inst/tinytest/test-misc.R b/inst/tinytest/test-misc.R index 09f15606..a94d325f 100644 --- a/inst/tinytest/test-misc.R +++ b/inst/tinytest/test-misc.R @@ -6,11 +6,15 @@ f = function () { tinyplot(Sepal.Length ~ Petal.Length, data = iris, type = "n") } expect_snapshot_plot(f, label = "type_n") -# empty plot(s) f = function () { tinyplot(Sepal.Length ~ Petal.Length | Species, data = iris, type = "n") } expect_snapshot_plot(f, label = "type_n_by") +f = function () { + tinyplot(Sepal.Length ~ Petal.Length | Species, data = iris, type = "l", empty = TRUE) +} +expect_snapshot_plot(f, label = "type_l_empty") + # log axes f = function() { diff --git a/man/tinyplot.Rd b/man/tinyplot.Rd index 84cafc55..6498fcf9 100644 --- a/man/tinyplot.Rd +++ b/man/tinyplot.Rd @@ -50,6 +50,7 @@ tinyplot(x, ...) file = NULL, width = NULL, height = NULL, + empty = FALSE, ... ) @@ -186,7 +187,8 @@ should be taken. A matrix is converted to a data frame.} for lines, "b" for both points and lines, "c" for empty points joined by lines, "o" for overplotted points and lines, "s" and "S" for stair steps, and "h" for histogram-like vertical lines. Specifying "n" produces an empty -plot over the extent of the data, but with no internal elements. +plot over the extent of the data, but with no internal elements (see also +the \code{empty} argument below). \item Additional tinyplot types: "boxplot" for boxplots, "density" for densities, "polygon" or "polypath" for polygons, "pointrange" or"errorbar" for segment intervals, and "ribbon" or "area" for polygon intervals (where @@ -400,6 +402,14 @@ graphics windows.} \code{width} (above) apply, e.g. will default to \code{tpar("file.height")} if not specified.} +\item{empty}{logical indicating whether the interior plot region should be +left empty. The default is \code{FALSE}. Setting to \code{TRUE} has a similar effect +to invoking \code{type = "n"} above, except that any legend artifacts owing to a +particular plot type (e.g., lines for \code{type = "l"} or squares for +\code{type = "area"}) will still be drawn correctly alongside the empty plot. In +contrast,\code{type = "n"} implicitly assumes a scatterplot and so any legend +will only depict points.} + \item{formula}{a \code{formula} that optionally includes grouping variable(s) after a vertical bar, e.g. \code{y ~ x | z}. One-sided formulae are also permitted, e.g. \code{~ y | z}. Note that the \code{formula} and \code{x} arguments