diff --git a/R/tinyAxis.R b/R/tinyAxis.R new file mode 100644 index 00000000..8aaf3c66 --- /dev/null +++ b/R/tinyAxis.R @@ -0,0 +1,20 @@ +## auxiliary Axis() interface with different parameter combinations based on type +tinyAxis = function(x = NULL, ..., type = "standard") { + type = match.arg(type, c("standard", "none", "labels", "ticks", "axis")) + if (type == "none") { + invisible(numeric(0L)) + } else { + args = list(x = x, ...) + if (type == "labels") { + args$tick = FALSE + } else if (type == "ticks") { + args$lwd = 0 + if (!("lwd.ticks" %in% names(args))) args$lwd.ticks = 1 + } else if (type == "axis") { + args$lwd.ticks = 0 + } else { + args$tick = TRUE + } + do.call("Axis", args) + } +} diff --git a/R/tinyplot.R b/R/tinyplot.R index 4fbd62ec..8ac52ca2 100644 --- a/R/tinyplot.R +++ b/R/tinyplot.R @@ -112,11 +112,17 @@ #' @param ylab a label for the y axis, defaults to a description of y. #' @param ann a logical value indicating whether the default annotation (title #' and x and y axis labels) should appear on the plot. -#' @param axes a logical value indicating whether both axes should be drawn on -#' the plot. Use `graphical parameter` "xaxt" or "yaxt" to suppress just one of -#' the axes. +#' @param axes logical or character. Should axes be drawn (`TRUE` or `FALSE`)? +#' Or alternatively what type of axes should be drawn: `"standard" (with +#' axis, ticks, and labels; equivalent to `TRUE`), "none" (no axes; +#' equivalent to `FALSE`), `"ticks"` (only ticks and labels without axis line), +#' `"labels"` (only labels without ticks and axis line), `"axis"` (only axis +#' line and labels but no ticks). To control this separately for the two +#' axes, use the character specifications for `xaxt` and/or `yaxt`. #' @param frame.plot a logical indicating whether a box should be drawn around #' the plot. Can also use `frame` as an acceptable argument alias. +#' The default is to draw a frame if both axis types (set via `axes`, `xaxt`, +#' or `yaxt`) include axis lines. #' @param grid argument for plotting a background panel grid, one of either: #' - a logical (i.e., `TRUE` to draw the grid), or #' - a panel grid plotting function like `grid()`. @@ -267,6 +273,8 @@ #' @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. +#' @param xaxt,yaxt character specifying the type of x-axis and y-axis, respectively. +#' See `axes` for the possible values. #' @param ... other graphical parameters. See \code{\link[graphics]{par}} or #' the "Details" section of \code{\link[graphics]{plot}}. #' @@ -482,7 +490,7 @@ tinyplot.default = function( ylab = NULL, ann = par("ann"), axes = TRUE, - frame.plot = axes, + frame.plot = NULL, asp = NA, grid = NULL, palette = NULL, @@ -506,6 +514,8 @@ tinyplot.default = function( width = NULL, height = NULL, empty = FALSE, + xaxt = NULL, + yaxt = NULL, ... ) { @@ -519,6 +529,21 @@ tinyplot.default = function( xlabs = NULL + ## handle defaults of axes, xaxt, yaxt, frame.plot + ## - convert axes to character if necessary + ## - set defaults of xaxt/yaxt (if these are NULL) based on axes + ## - set logical axes based on xaxt/yaxt + ## - set frame.plot default based on xaxt/yaxt + if (!is.character(axes)) axes = if (isFALSE(axes)) "none" else "standard" + axis_types = c("standard", "none", "labels", "ticks", "axis") + axes = match.arg(axes, axis_types) + if (is.null(xaxt)) xaxt = axes + if (is.null(yaxt)) yaxt = axes + xaxt = substr(match.arg(xaxt, axis_types), 1L, 1L) + yaxt = substr(match.arg(yaxt, axis_types), 1L, 1L) + axes = any(c(xaxt, yaxt) != "n") + if (is.null(frame.plot) || !is.logical(frame.plot)) frame.plot = all(c(xaxt, yaxt) %in% c("s", "a")) + # Write plot to output file or window with fixed dimensions setup_device(file = file, width = width, height = height) if (!is.null(file)) on.exit(dev.off(), add = TRUE) @@ -1076,27 +1101,27 @@ tinyplot.default = function( yside = 2 } - # axes, plot.frame and grid + # axes, frame.plot and grid if (isTRUE(axes)) { if (isTRUE(frame.plot)) { # if plot frame is true then print axes per normal... if (type %in% c("pointrange", "errorbar", "ribbon", "boxplot", "p") && !is.null(xlabs)) { - Axis(x, side = xside, at = xlabs, labels = names(xlabs)) + tinyAxis(x, side = xside, at = xlabs, labels = names(xlabs), type = xaxt) } else { - Axis(x, side = xside) + tinyAxis(x, side = xside, type = xaxt) } - Axis(y, side = yside) + tinyAxis(y, side = yside, type = yaxt) } else { # ... else only print the "outside" axes. if (ii %in% oxaxis) { if (type %in% c("pointrange", "errorbar", "ribbon", "boxplot", "p") && !is.null(xlabs)) { - Axis(x, side = xside, at = xlabs, labels = names(xlabs)) + tinyAxis(x, side = xside, at = xlabs, labels = names(xlabs), type = xaxt) } else { - Axis(x, side = xside) + tinyAxis(x, side = xside, type = xaxt) } } if (ii %in% oyaxis) { - Axis(y, side = yside) + tinyAxis(y, side = yside, type = yaxt) } } } @@ -1332,7 +1357,7 @@ tinyplot.formula = function( ylab = NULL, ann = par("ann"), axes = TRUE, - frame.plot = axes, + frame.plot = NULL, asp = NA, grid = NULL, pch = NULL, diff --git a/man/tinyplot.Rd b/man/tinyplot.Rd index 894d8137..c4eea58a 100644 --- a/man/tinyplot.Rd +++ b/man/tinyplot.Rd @@ -54,7 +54,7 @@ tinyplot(x, ...) ylab = NULL, ann = par("ann"), axes = TRUE, - frame.plot = axes, + frame.plot = NULL, asp = NA, grid = NULL, palette = NULL, @@ -78,6 +78,8 @@ tinyplot(x, ...) width = NULL, height = NULL, empty = FALSE, + xaxt = NULL, + yaxt = NULL, ... ) @@ -95,7 +97,7 @@ tinyplot(x, ...) ylab = NULL, ann = par("ann"), axes = TRUE, - frame.plot = axes, + frame.plot = NULL, asp = NA, grid = NULL, pch = NULL, @@ -217,12 +219,13 @@ the range of the \code{finite} values to be plotted should be used.} \item{ann}{a logical value indicating whether the default annotation (title and x and y axis labels) should appear on the plot.} -\item{axes}{a logical value indicating whether both axes should be drawn on -the plot. Use \verb{graphical parameter} "xaxt" or "yaxt" to suppress just one of -the axes.} +\item{axes}{logical or character. Should axes be drawn (\code{TRUE} or \code{FALSE})? +Or alternatively what type of axes should be drawn: \verb{"standard" (with axis, ticks, and labels; equivalent to }TRUE\verb{), "none" (no axes; equivalent to }FALSE\verb{), }"ticks"\verb{(only ticks and labels without axis line),}"labels"\verb{(only labels without ticks and axis line),}"axis"\verb{(only axis line and labels but no ticks). To control this separately for the two axes, use the character specifications for}xaxt\code{and/or}yaxt`.} \item{frame.plot}{a logical indicating whether a box should be drawn around -the plot. Can also use \code{frame} as an acceptable argument alias.} +the plot. Can also use \code{frame} as an acceptable argument alias. +The default is to draw a frame if both axis types (set via \code{axes}, \code{xaxt}, +or \code{yaxt}) include axis lines.} \item{asp}{the y/xy/x aspect ratio, see \code{plot.window}.} @@ -420,6 +423,9 @@ particular plot type (e.g., lines for \code{type = "l"} or squares for contrast,\code{type = "n"} implicitly assumes a scatterplot and so any legend will only depict points.} +\item{xaxt, yaxt}{character specifying the type of x-axis and y-axis, respectively. +See \code{axes} for the possible values.} + \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