diff --git a/DESCRIPTION b/DESCRIPTION index 4f4886b2..89819c42 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -54,7 +54,7 @@ Suggests: knitr Config/Needs/website: altdoc (>= 0.7.2), future.apply Encoding: UTF-8 -RoxygenNote: 7.3.3 URL: https://grantmcdermott.com/tinyplot/ BugReports: https://github.com/grantmcdermott/tinyplot/issues Roxygen: list(markdown = TRUE) +Config/roxygen2/version: 8.0.0 diff --git a/NEWS.md b/NEWS.md index 0b8df3e2..96267a8f 100644 --- a/NEWS.md +++ b/NEWS.md @@ -32,9 +32,22 @@ where the formatting is also better._ ### New features +- 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) - New `"dynamic"` theme that now serves as the foundation for all other dynamic (tiny)themes. (#549 @grantmcdermott) +### Bug fixes + +- Fixed `grid = grid()` not drawing grid lines on all facets. That said, logical + or character inputs (e.g., `grid = TRUE`, `grid = "xy"`) remain the more + idiomatic way to generate a background grid in `tinyplot`. + (#193 @grantmcdermott) + ## v0.6.1 ### Aesthetic changes diff --git a/R/assertions.R b/R/assertions.R index 5e48f97d..a2231abc 100644 --- a/R/assertions.R +++ b/R/assertions.R @@ -90,6 +90,15 @@ assert_length = function(x, len = 1, null.ok = FALSE, name = as.character(substi } } +assert_grid = function(x, null.ok = FALSE, name = as.character(substitute(x))) { + if (is.null(x) && isTRUE(null.ok)) return(invisible(TRUE)) + if (is.logical(x) && length(x) == 1) return(invisible(TRUE)) + valid_strings = c("x", "y", "X", "Y", "xy", "xY", "Xy", "XY") + if (is.character(x) && length(x) == 1 && x %in% valid_strings) return(invisible(TRUE)) + msg = sprintf("`%s` must be a logical flag or a character string combining x/X and/or y/Y (e.g., \"xy\", \"XY\", \"xY\")", name) + stop(msg, call. = FALSE) +} + assert_logical = function(x, null.ok = FALSE, name = as.character(substitute(x))) { if (is.null(x) && isTRUE(null.ok)) { return(invisible(TRUE)) diff --git a/R/facet.R b/R/facet.R index 3d1b1b95..32eabe69 100644 --- a/R/facet.R +++ b/R/facet.R @@ -514,34 +514,54 @@ draw_facet_window = function( # panel grid lines if (is.null(grid)) grid = get_tpar("grid", tpar_list = tpars) - if (!is.null(grid)) { - if (is.logical(grid)) { - ## If grid is TRUE create a default grid. Rather than just calling the default grid() - ## abline(... = pretty(extendrange(...)), ...) is used. Reason: pretty() is generic - ## and works better for axes based on date/time classes. Exception: For axes in logs, - ## resort to using grid() which is likely better handled there. - if (isTRUE(grid)) { - gnx = gny = NULL + if (!is.null(grid) && !isFALSE(grid)) { + gcol = get_tpar("grid.col", tpar_list = tpars) + glty = get_tpar("grid.lty", tpar_list = tpars) + glwd = get_tpar("grid.lwd", tpar_list = tpars) + + if (isTRUE(grid)) { + draw_x = draw_y = TRUE + fine_x = fine_y = FALSE + } else if (is.character(grid)) { + draw_x = grepl("x", grid, fixed = TRUE) || grepl("X", grid, fixed = TRUE) + draw_y = grepl("y", grid, fixed = TRUE) || grepl("Y", grid, fixed = TRUE) + fine_x = grepl("x", grid, fixed = TRUE) + fine_y = grepl("y", grid, fixed = TRUE) + } else { + eval(grid) # issue #193 + draw_x = draw_y = FALSE + } + + if (draw_x || draw_y) { + + if (draw_x) { if (!is.null(xaxb)) { - abline(v = xaxb, col = get_tpar("grid.col", tpar_list = tpars), lty = get_tpar("grid.lty", tpar_list = tpars), lwd = get_tpar("grid.lwd", tpar_list = tpars)) - gnx = NA - } else if (!any(c(par("xlog"), type == "boxplot"))) { + xg = xaxb + } else { xg = if (!inherits(x, c("POSIXt", "Date"))) axTicks(side = 1) else axTicksDateTime(side = 1, x = x) - abline(v = xg, col = get_tpar("grid.col", tpar_list = tpars), lty = get_tpar("grid.lty", tpar_list = tpars), lwd = get_tpar("grid.lwd", tpar_list = tpars)) - gnx = NA } + if (fine_x && !par("xlog") && length(xg) >= 2L) { + xg = as.numeric(xg) + half = (xg[2L] - xg[1L]) / 2 + xg = seq(xg[1L] - half, xg[length(xg)] + half, by = half) + } + abline(v = xg, col = gcol, lty = glty, lwd = glwd) + } + + if (draw_y) { if (!is.null(yaxb)) { - abline(h = yaxb, col = get_tpar("grid.col", tpar_list = tpars), lty = get_tpar("grid.lty", tpar_list = tpars), lwd = get_tpar("grid.lwd", tpar_list = tpars)) - gny = NA - } else if (!any(c(par("ylog"), type == "boxplot"))) { + yg = yaxb + } else { yg = if (!inherits(y, c("POSIXt", "Date"))) axTicks(side = 2) else axTicksDateTime(side = 2, x = x) - abline(h = yg, col = get_tpar("grid.col", tpar_list = tpars), lty = get_tpar("grid.lty", tpar_list = tpars), lwd = get_tpar("grid.lwd", tpar_list = tpars)) - gny = NA } - grid(nx = gnx, ny = gny, col = get_tpar("grid.col", tpar_list = tpars), lty = get_tpar("grid.lty", tpar_list = tpars), lwd = get_tpar("grid.lwd", tpar_list = tpars)) + if (fine_y && !par("ylog") && length(yg) >= 2L) { + yg = as.numeric(yg) + half = (yg[2L] - yg[1L]) / 2 + yg = seq(yg[1L] - half, yg[length(yg)] + half, by = half) + } + abline(h = yg, col = gcol, lty = glty, lwd = glwd) } - } else { - grid + } } diff --git a/R/tinyplot.R b/R/tinyplot.R index ef289e86..f21f6356 100644 --- a/R/tinyplot.R +++ b/R/tinyplot.R @@ -197,8 +197,15 @@ #' 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 +#' @param grid argument for plotting a background panel grid, one of: +#' - a logical (i.e., `TRUE` to draw the grid on both axes). +#' - a character string controlling which axes get grid lines and at what +#' resolution. Uppercase letters (`"X"`, `"Y"`, `"XY"`) draw grid lines at +#' the standard axis tick positions (with the latter equivalent to `TRUE`), +#' while lowercase letters (`"x"`, `"y"`, `"xy"`) draw a finer grid with +#' additional lines at the midpoints between ticks. (Note: the finer grid +#' has no effect on log-scale axes, since tick positions already include +#' intermediate values.) #' - a panel grid plotting function like `grid()`. #' Note that this argument replaces the `panel.first` and `panel.last` #' arguments from base `plot()` and tries to make the process more seamless @@ -653,6 +660,12 @@ tinyplot.default = function( par_first = get_saved_par("first") if (is.null(par_first)) set_saved_par("first", par()) + # Validate grid only for simple values; skip for unevaluated calls like grid() + # which are passed as language objects from tinyplot.formula via substitute(). (#193) + if (!is.null(grid) && !is.call(grid)) { + assert_grid(grid, null.ok = TRUE, name = "grid") + } + # save for tinyplot_add() assert_logical(add) if (!add) { @@ -1580,7 +1593,7 @@ tinyplot.formula = function( axes = axes, frame.plot = frame.plot, asp = asp, - grid = grid, + grid = substitute(grid), # issue #193 legend_args = legend_args, pch = pch, col = col, diff --git a/R/tpar.R b/R/tpar.R index 763b6374..bedb76df 100644 --- a/R/tpar.R +++ b/R/tpar.R @@ -65,7 +65,7 @@ #' * `grid.col`: Character or (integer) numeric that specifies the color of the panel grid lines. Defaults to `"lightgray"`. #' * `grid.lty`: Character or (integer) numeric that specifies the line type of the panel grid lines. Defaults to `"dotted"`. #' * `grid.lwd`: Non-negative numeric giving the line width of the panel grid lines. Defaults to `1`. -#' * `grid`: Logical indicating whether a background panel grid should be added to plots automatically. Defaults to `NULL`, which is equivalent to `FALSE`. +#' * `grid`: Logical or character indicating whether a background panel grid should be added to plots automatically. Defaults to `NULL`, which is equivalent to `FALSE`. In addition to logical values, a character string can be used to control axis-specific grids: uppercase letters (`"X"`, `"Y"`, `"XY"`) draw grid lines at the standard axis tick positions (equivalent to `TRUE`), while lowercase letters (`"x"`, `"y"`, `"xy"`) draw a finer grid with additional lines at the midpoints between ticks. #' * `lmar`: A numeric vector of form `c(inner, outer)` that gives the margin padding, in terms of lines, around the automatic `tinyplot` legend. Defaults to `c(1.0, 0.1)`. The inner margin is the gap between the legend and the plot region, and the outer margin is the gap between the legend and the edge of the graphics device. #' * `palette.qualitative`: Palette for qualitative colors. See the `palette` argument in `?tinyplot`. #' * `palette.sequential`: Palette for sequential colors. See the `palette` argument in `?tinyplot`. @@ -276,7 +276,7 @@ assert_tpar = function(.tpar) { assert_numeric(.tpar[["lmar"]], len = 2, null.ok = TRUE, name = "lmar") assert_numeric(.tpar[["ribbon.alpha"]], len = 1, lower = 0, upper = 1, null.ok = TRUE, name = "ribbon.alpha") assert_numeric(.tpar[["grid.lwd"]], len = 1, lower = 0, null.ok = TRUE, name = "grid.lwd") - assert_flag(.tpar[["grid"]], null.ok = TRUE, name = "grid") + assert_grid(.tpar[["grid"]], null.ok = TRUE, name = "grid") assert_numeric(.tpar[["file.res"]], len = 1, lower = 0, null.ok = TRUE, name = "file.res") assert_numeric(.tpar[["file.height"]], len = 1, lower = 0, null.ok = TRUE, name = "file.height") assert_numeric(.tpar[["file.width"]], len = 1, lower = 0, null.ok = TRUE, name = "file.width") diff --git a/inst/tinytest/_tinysnapshot/flip_boxplot.svg b/inst/tinytest/_tinysnapshot/flip_boxplot.svg index 9718c6cb..15521167 100644 --- a/inst/tinytest/_tinysnapshot/flip_boxplot.svg +++ b/inst/tinytest/_tinysnapshot/flip_boxplot.svg @@ -62,18 +62,18 @@ - - - - - - + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_date_true.svg b/inst/tinytest/_tinysnapshot/grid_date_true.svg new file mode 100644 index 00000000..ea0d6dc7 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_date_true.svg @@ -0,0 +1,197 @@ + + + + + + + + + + + + + +date: grid = TRUE +ds +y + + + + + + +2016 +2018 +2020 +2022 +2024 + + + + + + + +-2 +0 +2 +4 +6 +8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_date_xy.svg b/inst/tinytest/_tinysnapshot/grid_date_xy.svg new file mode 100644 index 00000000..6f8b047b --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_date_xy.svg @@ -0,0 +1,209 @@ + + + + + + + + + + + + + +date: grid = "xy" +ds +y + + + + + + +2016 +2018 +2020 +2022 +2024 + + + + + + + +-2 +0 +2 +4 +6 +8 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_facet_xy.svg b/inst/tinytest/_tinysnapshot/grid_facet_xy.svg new file mode 100644 index 00000000..3393dd1b --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_facet_xy.svg @@ -0,0 +1,118 @@ + + + + + + + + + + + + + + + + +factor(cyl) +4 +6 +8 + + + + + + + +faceted: grid = "xy" +mpg +wt + + +10 +15 +20 +25 +30 +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_func_facet.svg b/inst/tinytest/_tinysnapshot/grid_func_facet.svg new file mode 100644 index 00000000..5f654928 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_func_facet.svg @@ -0,0 +1,395 @@ + + + + + + + + + + + + + + + 5 + 6 + 7 +- - +- - +- - +Sepal.Length + + + + + + + +grid = grid() +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 + +setosa + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 +2 +3 +4 +5 +6 +7 + + + + + + + + + +4.5 +5.0 +5.5 +6.0 +6.5 +7.0 +7.5 +8.0 + +versicolor + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +1 +2 +3 +4 +5 +6 +7 + + + + + + + + + +4.5 +5.0 +5.5 +6.0 +6.5 +7.0 +7.5 +8.0 + +virginica + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_log_true.svg b/inst/tinytest/_tinysnapshot/grid_log_true.svg new file mode 100644 index 00000000..4f2e0981 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_log_true.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + +log: grid = TRUE +Index +1:100 + + + + + + + + +1 +2 +5 +10 +20 +50 +100 + + + + + + + + +1 +2 +5 +10 +20 +50 +100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_log_xy.svg b/inst/tinytest/_tinysnapshot/grid_log_xy.svg new file mode 100644 index 00000000..87a4835b --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_log_xy.svg @@ -0,0 +1,186 @@ + + + + + + + + + + + + + +log: grid = "xy" +Index +1:100 + + + + + + + + +1 +2 +5 +10 +20 +50 +100 + + + + + + + + +1 +2 +5 +10 +20 +50 +100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_logx_x.svg b/inst/tinytest/_tinysnapshot/grid_logx_x.svg new file mode 100644 index 00000000..3ebd941c --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_logx_x.svg @@ -0,0 +1,177 @@ + + + + + + + + + + + + + +log x: grid = "x" +Index +1:100 + + + + + + + + +1 +2 +5 +10 +20 +50 +100 + + + + + + + +0 +20 +40 +60 +80 +100 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_numeric_Y.svg b/inst/tinytest/_tinysnapshot/grid_numeric_Y.svg new file mode 100644 index 00000000..b4b8cdba --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_numeric_Y.svg @@ -0,0 +1,98 @@ + + + + + + + + + + + + + +numeric: grid = "Y" +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_numeric_false.svg b/inst/tinytest/_tinysnapshot/grid_numeric_false.svg new file mode 100644 index 00000000..38f7f303 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_numeric_false.svg @@ -0,0 +1,94 @@ + + + + + + + + + + + + + +numeric: grid = FALSE +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_numeric_true.svg b/inst/tinytest/_tinysnapshot/grid_numeric_true.svg new file mode 100644 index 00000000..f0a352fd --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_numeric_true.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + +numeric: grid = TRUE +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_numeric_upper_xy.svg b/inst/tinytest/_tinysnapshot/grid_numeric_upper_xy.svg new file mode 100644 index 00000000..d851b4b0 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_numeric_upper_xy.svg @@ -0,0 +1,103 @@ + + + + + + + + + + + + + +numeric: grid = "XY" +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_numeric_x.svg b/inst/tinytest/_tinysnapshot/grid_numeric_x.svg new file mode 100644 index 00000000..30eccf76 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_numeric_x.svg @@ -0,0 +1,105 @@ + + + + + + + + + + + + + +numeric: grid = "x" +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_numeric_xy.svg b/inst/tinytest/_tinysnapshot/grid_numeric_xy.svg new file mode 100644 index 00000000..9a020c14 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_numeric_xy.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + +numeric: grid = "xy" +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/grid_theme_xy.svg b/inst/tinytest/_tinysnapshot/grid_theme_xy.svg new file mode 100644 index 00000000..c5f96b75 --- /dev/null +++ b/inst/tinytest/_tinysnapshot/grid_theme_xy.svg @@ -0,0 +1,114 @@ + + + + + + + + + + + + + +theme: grid = "xy" +mpg +wt + + + + + + +10 +15 +20 +25 +30 + + + + + +2 +3 +4 +5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/inst/tinytest/_tinysnapshot/tinytheme_dynamic_boxplot_flip.svg b/inst/tinytest/_tinysnapshot/tinytheme_dynamic_boxplot_flip.svg index 79bdee34..d607a6c3 100644 --- a/inst/tinytest/_tinysnapshot/tinytheme_dynamic_boxplot_flip.svg +++ b/inst/tinytest/_tinysnapshot/tinytheme_dynamic_boxplot_flip.svg @@ -66,12 +66,6 @@ - - - - - - @@ -79,6 +73,12 @@ + + + + + + diff --git a/inst/tinytest/_tinysnapshot/tinytheme_dynamic_x_boxplot.svg b/inst/tinytest/_tinysnapshot/tinytheme_dynamic_x_boxplot.svg index bcf23ce9..d538e0c9 100644 --- a/inst/tinytest/_tinysnapshot/tinytheme_dynamic_x_boxplot.svg +++ b/inst/tinytest/_tinysnapshot/tinytheme_dynamic_x_boxplot.svg @@ -66,6 +66,12 @@ + + + + + + @@ -73,12 +79,6 @@ - - - - - - diff --git a/inst/tinytest/test-grid.R b/inst/tinytest/test-grid.R new file mode 100644 index 00000000..c320966e --- /dev/null +++ b/inst/tinytest/test-grid.R @@ -0,0 +1,84 @@ +source("helpers.R") +using("tinysnapshot") + +set.seed(42) +dat = data.frame( + y = cumsum(rnorm(120)), + ds = seq(as.Date("2015-01-01"), as.Date("2024-12-01"), by = "month") +) + +# Numeric axes + +f = function() plt(wt ~ mpg, mtcars, grid = TRUE, main = "numeric: grid = TRUE") +expect_snapshot_plot(f, label = "grid_numeric_true") + +f = function() plt(wt ~ mpg, mtcars, grid = "XY", main = "numeric: grid = \"XY\"") +expect_snapshot_plot(f, label = "grid_numeric_upper_xy") + +f = function() plt(wt ~ mpg, mtcars, grid = "xy", main = "numeric: grid = \"xy\"") +expect_snapshot_plot(f, label = "grid_numeric_xy") + +f = function() plt(wt ~ mpg, mtcars, grid = "x", main = "numeric: grid = \"x\"") +expect_snapshot_plot(f, label = "grid_numeric_x") + +f = function() plt(wt ~ mpg, mtcars, grid = "Y", main = "numeric: grid = \"Y\"") +expect_snapshot_plot(f, label = "grid_numeric_Y") + +f = function() plt(wt ~ mpg, mtcars, grid = FALSE, main = "numeric: grid = FALSE") +expect_snapshot_plot(f, label = "grid_numeric_false") + +# Date axes + +f = function() plt(y ~ ds, dat, grid = TRUE, main = "date: grid = TRUE") +expect_snapshot_plot(f, label = "grid_date_true") + +f = function() plt(y ~ ds, dat, grid = "xy", main = "date: grid = \"xy\"") +expect_snapshot_plot(f, label = "grid_date_xy") + +# Log axes + +f = function() plt(1:100, log = "xy", grid = TRUE, main = "log: grid = TRUE") +expect_snapshot_plot(f, label = "grid_log_true") + +f = function() plt(1:100, log = "xy", grid = "xy", main = "log: grid = \"xy\"") +expect_snapshot_plot(f, label = "grid_log_xy") + +# Single axis on log + +f = function() plt(1:100, log = "x", grid = "x", main = "log x: grid = \"x\"") +expect_snapshot_plot(f, label = "grid_logx_x") + +# Faceted + +f = function() { + tinytheme("clean2", grid = "xy") + plt(wt ~ mpg | factor(cyl), mtcars, main = "faceted: grid = \"xy\"") + tinytheme() +} +expect_snapshot_plot(f, label = "grid_facet_xy") + +# Via theme + +f = function() { + tinytheme("clean", grid = "xy") + plt(wt ~ mpg, mtcars, main = "theme: grid = \"xy\"") + tinytheme() +} +expect_snapshot_plot(f, label = "grid_theme_xy") + +# grid = grid() with facets (issue #193) + +f = function() { + plt( + Sepal.Length ~ Petal.Length | Sepal.Length, data = iris, + facet = ~Species, pch = 19, + grid = grid(), + main = "grid = grid()" + ) +} +expect_snapshot_plot(f, label = "grid_func_facet") + +# Input validation + +expect_error(plt(wt ~ mpg, mtcars, grid = "zz")) +expect_error(plt(wt ~ mpg, mtcars, grid = "abc")) diff --git a/man/tinyplot-package.Rd b/man/tinyplot-package.Rd index 13b5d091..5684b661 100644 --- a/man/tinyplot-package.Rd +++ b/man/tinyplot-package.Rd @@ -20,6 +20,7 @@ Useful links: Authors: \itemize{ + \item Grant McDermott \email{contact@grantmcdermott.com} (\href{https://orcid.org/0000-0001-7883-8573}{ORCID}) \item Vincent Arel-Bundock \email{vincent.arel-bundock@umontreal.ca} (\href{https://orcid.org/0000-0003-1995-6531}{ORCID}) \item Achim Zeileis \email{Achim.Zeileis@R-project.org} (\href{https://orcid.org/0000-0003-0918-3766}{ORCID}) } diff --git a/man/tinyplot.Rd b/man/tinyplot.Rd index 503f1579..339dc7ce 100644 --- a/man/tinyplot.Rd +++ b/man/tinyplot.Rd @@ -331,9 +331,16 @@ 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{grid}{argument for plotting a background panel grid, one of either: +\item{grid}{argument for plotting a background panel grid, one of: \itemize{ -\item a logical (i.e., \code{TRUE} to draw the grid), or +\item a logical (i.e., \code{TRUE} to draw the grid on both axes). +\item a character string controlling which axes get grid lines and at what +resolution. Uppercase letters (\code{"X"}, \code{"Y"}, \code{"XY"}) draw grid lines at +the standard axis tick positions (with the latter equivalent to \code{TRUE}), +while lowercase letters (\code{"x"}, \code{"y"}, \code{"xy"}) draw a finer grid with +additional lines at the midpoints between ticks. (Note: the finer grid +has no effect on log-scale axes, since tick positions already include +intermediate values.) \item a panel grid plotting function like \code{grid()}. Note that this argument replaces the \code{panel.first} and \code{panel.last} arguments from base \code{plot()} and tries to make the process more seamless diff --git a/man/tpar.Rd b/man/tpar.Rd index c1fc5914..eea89829 100644 --- a/man/tpar.Rd +++ b/man/tpar.Rd @@ -76,7 +76,7 @@ you should rather use \code{par()} instead. \item \code{grid.col}: Character or (integer) numeric that specifies the color of the panel grid lines. Defaults to \code{"lightgray"}. \item \code{grid.lty}: Character or (integer) numeric that specifies the line type of the panel grid lines. Defaults to \code{"dotted"}. \item \code{grid.lwd}: Non-negative numeric giving the line width of the panel grid lines. Defaults to \code{1}. -\item \code{grid}: Logical indicating whether a background panel grid should be added to plots automatically. Defaults to \code{NULL}, which is equivalent to \code{FALSE}. +\item \code{grid}: Logical or character indicating whether a background panel grid should be added to plots automatically. Defaults to \code{NULL}, which is equivalent to \code{FALSE}. In addition to logical values, a character string can be used to control axis-specific grids: uppercase letters (\code{"X"}, \code{"Y"}, \code{"XY"}) draw grid lines at the standard axis tick positions (equivalent to \code{TRUE}), while lowercase letters (\code{"x"}, \code{"y"}, \code{"xy"}) draw a finer grid with additional lines at the midpoints between ticks. \item \code{lmar}: A numeric vector of form \code{c(inner, outer)} that gives the margin padding, in terms of lines, around the automatic \code{tinyplot} legend. Defaults to \code{c(1.0, 0.1)}. The inner margin is the gap between the legend and the plot region, and the outer margin is the gap between the legend and the edge of the graphics device. \item \code{palette.qualitative}: Palette for qualitative colors. See the \code{palette} argument in \code{?tinyplot}. \item \code{palette.sequential}: Palette for sequential colors. See the \code{palette} argument in \code{?tinyplot}.