diff --git a/NAMESPACE b/NAMESPACE index 5c755d45..ffa51202 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -8,15 +8,23 @@ export(get_saved_par) export(plt) export(tinyplot) export(tpar) +export(type_area) export(type_boxplot) export(type_errorbar) export(type_glm) export(type_hist) export(type_histogram) export(type_jitter) +export(type_lines) export(type_lm) export(type_loess) +export(type_pointrange) +export(type_points) +export(type_polygon) export(type_polypath) +export(type_rect) +export(type_ribbon) +export(type_segments) export(type_spline) importFrom(grDevices,adjustcolor) importFrom(grDevices,as.raster) diff --git a/NEWS.md b/NEWS.md index 4a6fbda1..cf59900a 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,7 +1,6 @@ # News _If you are viewing this file on CRAN, please check the -http://www.polljunkie.com/poll/qnbeij/fini [latest NEWS](https://grantmcdermott.com/tinyplot/NEWS.html) on our website where the formatting is also better._ diff --git a/R/type_area.R b/R/type_area.R index 229d9eec..ff35c051 100644 --- a/R/type_area.R +++ b/R/type_area.R @@ -1,3 +1,5 @@ +#' @rdname type_ribbon +#' @export type_area = function() { out = list( draw = NULL, diff --git a/R/type_boxplot.R b/R/type_boxplot.R index 608f1871..dd632b06 100644 --- a/R/type_boxplot.R +++ b/R/type_boxplot.R @@ -1,6 +1,23 @@ #' Boxplot type +#' +#' @description Type function for producing box-and-whisker plots. +#' Arguments are passed to \code{\link[graphics]{boxplot}}, although `tinyplot` +#' scaffolding allows added functionality such as grouping and faceting. #' #' @inheritParams graphics::boxplot +#' @examples +#' # "boxplot" type convenience string +#' tinyplot(count ~ spray, data = InsectSprays, type = "boxplot") +#' +#' # Note: Specifying the type here is redundant. Like base plot, tinyplot +#' # automatically produces a boxplot if x is a factor and y is numeric +#' tinyplot(count ~ spray, data = InsectSprays) +#' +#' # Use `type_boxplot()` to pass extra arguments for customization +#' tinyplot( +#' count ~ spray, data = InsectSprays, lty = 1, +#' type = type_boxplot(boxwex = 0.3, staplewex = 0, outline = FALSE) +#' ) #' @export type_boxplot = function( range = 1.5, diff --git a/R/type_errorbar.R b/R/type_errorbar.R index bb0e5f7d..d3cdbff4 100644 --- a/R/type_errorbar.R +++ b/R/type_errorbar.R @@ -1,6 +1,34 @@ -#' Error bars type -#' +#' Error bar and pointrange plot types +#' +#' @description Type function(s) for producing error bar and pointrange plots. +#' #' @inheritParams graphics::arrows +#' @examples +#' mod = lm(Sepal.Length ~ 0 + Sepal.Width * Species, iris) +#' mod = lm(mpg ~ wt * factor(am), mtcars) +#' coefs = data.frame(names(coef(mod)), coef(mod), confint(mod)) +#' colnames(coefs) = c("term", "est", "lwr", "upr") +#' +#' op = tpar(pch = 19) +#' +#' # "errorbar" and "pointrange" type convenience strings +#' with( +#' coefs, +#' tinyplot(x = term, y = est, ymin = lwr, ymax = upr, type = "errorbar") +#' ) +#' with( +#' coefs, +#' tinyplot(x = term, y = est, ymin = lwr, ymax = upr, type = "pointrange") +#' ) +#' +#' # Use `type_errorbar()` to pass extra arguments for customization +#' with( +#' coefs, +#' tinyplot(x = term, y = est, ymin = lwr, ymax = upr, type = type_errorbar(length = 0.2)) +#' ) +#' +#' tpar(op) +#' #' @export type_errorbar = function(length = 0.05) { out = list( diff --git a/R/type_glm.R b/R/type_glm.R index 48194c08..e2fd00bd 100644 --- a/R/type_glm.R +++ b/R/type_glm.R @@ -1,10 +1,19 @@ -#' GLM type +#' Generalized linear model plot type +#' +#' @description Type function for plotting a generalized model fit. +#' Arguments are passed to \code{\link[stats]{glm}}. #' #' @param se logical. If TRUE, confidence intervals are drawn. #' @inheritParams stats::glm #' @inheritParams stats::predict.glm #' @inheritParams stats::confint #' @importFrom stats glm predict +#' @examples +#' # "glm" type convenience string +#' tinyplot(am ~ mpg, data = mtcars, type = "glm") +#' +#' # Use `type_glm()` to pass extra arguments for customization +#' tinyplot(am ~ mpg, data = mtcars, type = type_glm(family = "binomial")) #' @export type_glm = function(family = "gaussian", se = TRUE, level = 0.95, type = "response") { assert_flag(se) diff --git a/R/type_histogram.R b/R/type_histogram.R index 5a087d43..24678b76 100644 --- a/R/type_histogram.R +++ b/R/type_histogram.R @@ -1,4 +1,4 @@ -#' Histogram type +#' Histogram plot type #' #' @md #' @description Type function for histogram plots. `type_hist` is an alias for @@ -14,6 +14,12 @@ #' it was larger). If breaks is a function, the x vector is supplied to it as #' the only argument (and the number of breaks is only limited by the amount of #' available memory). +#' @examples +#' # "histogram"/"hist" type convenience string(s) +#' tinyplot(Nile, type = "histogram") +#' +#' # Use `type_histogram()` to pass extra arguments for customization +#' tinyplot(Nile, type = type_histogram(breaks = 30)) #' @export type_histogram = function(breaks = "Sturges") { out = list( diff --git a/R/type_jitter.R b/R/type_jitter.R index ffb6fee1..c9e6e4d1 100644 --- a/R/type_jitter.R +++ b/R/type_jitter.R @@ -1,6 +1,16 @@ -#' Jittered points type +#' Jittered points plot type +#' +#' @description Type function for plotting jittered points. +#' Arguments are passed to \code{\link[base]{jitter}}. #' #' @inheritParams base::jitter +#' @inherit base::jitter details +#' @examples +#' # "jitter" type convenience string +#' tinyplot(Sepal.Length ~ Species, data = iris, type = "jitter") +#' +#' # Use `type_jitter()` to pass extra arguments for customization +#' tinyplot(Sepal.Length ~ Species, data = iris, type = type_jitter(factor = 0.5)) #' @export type_jitter = function(factor = 1, amount = NULL) { out = list( diff --git a/R/type_lines.R b/R/type_lines.R index 72636595..461ad738 100644 --- a/R/type_lines.R +++ b/R/type_lines.R @@ -1,3 +1,17 @@ +#' Lines plot type +#' +#' @description Type function for plotting lines. +#' +#' @inheritParams graphics::plot.default +#' +#' @examples +#' # "l" type convenience character string +#' tinyplot(circumference ~ age | Tree, data = Orange, type = "l") +#' +#' # Use `type_lines()` to pass extra arguments for customization +#' tinyplot(circumference ~ age | Tree, data = Orange, type = type_lines(type = "s")) +#' +#' @export type_lines = function(type = "l") { out = list( draw = draw_lines(type = type), diff --git a/R/type_lm.R b/R/type_lm.R index 36cf03f2..966217b7 100644 --- a/R/type_lm.R +++ b/R/type_lm.R @@ -1,7 +1,16 @@ -#' LM type -#' +#' Linear model plot type +#' +#' @description Type function for plotting a linear model fit. +#' Arguments are passed to \code{\link[stats]{lm}}. +#' #' @inheritParams type_glm #' @importFrom stats lm predict +#' @examples +#' # "lm" type convenience string +#' tinyplot(dist ~ speed, data = cars, type = "lm") +#' +#' # Use `type_lm()` to pass extra arguments for customization +#' tinyplot(dist ~ speed, data = cars, type = type_lm(level = 0.9)) #' @export type_lm = function(se = TRUE, level = 0.95) { assert_flag(se) @@ -35,7 +44,7 @@ data_lm = function(se, level, ...) { nd$ymax = p$conf.high nd$ymin = p$conf.low } else { - nd$y = predict(fit, nd) + nd$y = predict(fit, newdata = nd) } nd }) diff --git a/R/type_loess.R b/R/type_loess.R index 164a1d6f..3f751d31 100644 --- a/R/type_loess.R +++ b/R/type_loess.R @@ -1,4 +1,4 @@ -#' Loess type +#' Local polynomial regression plot type #' #' @description Type function for plotting a LOESS (LOcal regrESSion) fit. #' Arguments are passed to \code{\link[stats]{loess}}. diff --git a/R/type_pointrange.R b/R/type_pointrange.R index 0fc3bf27..7e252822 100644 --- a/R/type_pointrange.R +++ b/R/type_pointrange.R @@ -1,3 +1,5 @@ +#' @rdname type_errorbar +#' @export type_pointrange = function() { out = list( draw = draw_pointrange(), diff --git a/R/type_points.R b/R/type_points.R index 70232793..7ad73542 100644 --- a/R/type_points.R +++ b/R/type_points.R @@ -1,3 +1,19 @@ +#' Points plot type +#' +#' @description Type function for plotting points, i.e. a scatter plot. +#' +#' @examples +#' # "p" type convenience character string +#' tinyplot(dist ~ speed, data = cars, type = "p") +#' +#' # Same result with type_points() +#' tinyplot(dist ~ speed, data = cars, type = type_points()) +#' +#' # Note: Specifying the type here is redundant. Like base plot, tinyplot +#' # automatically produces a scatter plot if x and y are numeric +#' tinyplot(dist ~ speed, data = cars) +#' +#' @export type_points = function() { out = list( draw = draw_points(), diff --git a/R/type_polygon.R b/R/type_polygon.R index b4918cb1..fb0f9bde 100644 --- a/R/type_polygon.R +++ b/R/type_polygon.R @@ -1,6 +1,21 @@ -type_polygon = function() { +#' Polygon plot type +#' +#' @description Type function for plotting polygons. +#' Arguments are passed to \code{\link[graphics]{polygon}}. +#' +#' @inheritParams graphics::polygon +#' +#' @examples +#' # "polygon" type convenience character string +#' tinyplot(1:9, c(2,1,2,1,NA,2,1,2,1), type = "polygon") +#' +#' # Use `type_polygon()` to pass extra arguments for customization +#' tinyplot(1:9, c(2,1,2,1,NA,2,1,2,1), type = type_polygon(density = c(10, 20))) +#' +#' @export +type_polygon = function(density = NULL, angle = 45) { out = list( - draw = draw_polygon(), + draw = draw_polygon(density = density, angle = angle), data = NULL, name = "polygon" ) @@ -9,7 +24,7 @@ type_polygon = function() { } -draw_polygon = function() { +draw_polygon = function(density = density, angle = 45) { fun = function(ix, iy, icol, ibg, ilty = par("lty"), ilwd = par("lwd"), ...) { polygon( x = ix, @@ -17,7 +32,9 @@ draw_polygon = function() { border = icol, col = ibg, lty = ilty, - lwd = ilwd + lwd = ilwd, + density = density, + angle = angle ) } return(fun) diff --git a/R/type_polypath.R b/R/type_polypath.R index beb3edb4..29742787 100644 --- a/R/type_polypath.R +++ b/R/type_polypath.R @@ -1,6 +1,24 @@ -#' Polypath type +#' Polypath polygon type +#' +#' @description Type function for plotting polygons. +#' Arguments are passed to \code{\link[graphics]{polypath}}. #' #' @inheritParams graphics::polypath +#' +#' @examples +#' # "polypath" type convenience character string +#' tinyplot( +#' c(.1, .1, .6, .6, NA, .4, .4, .9, .9), +#' c(.1, .6, .6, .1, NA, .4, .9, .9, .4), +#' type = "polypath", fill = "grey" +#' ) +#' +#' # Use `type_polypath()` to pass extra arguments for customization +#' tinyplot( +#' c(.1, .1, .6, .6, NA, .4, .4, .9, .9), +#' c(.1, .6, .6, .1, NA, .4, .9, .9, .4), +#' type = type_polypath(rule = "evenodd"), fill = "grey" +#' ) #' @export type_polypath = function(rule = "winding") { draw_polypath = function() { diff --git a/R/type_rect.R b/R/type_rect.R index 4db4d1d2..173e021b 100644 --- a/R/type_rect.R +++ b/R/type_rect.R @@ -1,3 +1,29 @@ +#' Rectangle plot type +#' +#' @description Type function for plotting rectangles. +#' +#' @details Contrary to base \code{\link[graphics]{rect}}, rectangles in +#' [tinyplot] must be specified using the `xmin`, `ymin`,`xmax`, and `ymax` +#' arguments. +#' +#' @examples +#' i = 4*(0:10) +#' +#' # "rect" type convenience character string +#' tinyplot( +#' xmin = 100+i, ymin = 300+i, xmax = 150+i, ymax = 380+i, +#' by = i, fill = 0.2, +#' type = "rect" +#' ) +#' +#' # Same result with type_rect() +#' tinyplot( +#' xmin = 100+i, ymin = 300+i, xmax = 150+i, ymax = 380+i, +#' by = i, fill = 0.2, +#' type = type_rect() +#' ) +#' +#' @export type_rect = function() { out = list( draw = draw_rect(), diff --git a/R/type_ribbon.R b/R/type_ribbon.R index 691c7fed..222f0750 100644 --- a/R/type_ribbon.R +++ b/R/type_ribbon.R @@ -1,3 +1,38 @@ +#' Ribbon and area plot types +#' +#' @description Type constructor functions for producing polygon ribbons, which +#' define a `y` interval (usually spanning from `ymin` to `ymax`) for each +#' `x` value. Area plots are a special case of ribbon plot where `ymin` is +#' set to 0 and `ymax` is set to `y`. +#' +#' @examples +#' x = 1:100/10 +#' y = sin(x) +#' +#' # +#' ## Ribbon plots +#' +#' # "ribbon" convenience string +#' tinyplot(x = x, ymin = y-1, ymax = y+1, type = "ribbon") + +#' # Same result with type_ribbon() +#' tinyplot(x = x, ymin = y-1, ymax = y+1, type = type_ribbon()) +#' +#' # y will be added as a line if it is specified +#' tinyplot(x = x, y = y, ymin = y-1, ymax = y+1, type = "ribbon") +#' +#' # +#' ## Area plots +#' +#' # "area" type convenience string +#' tinyplot(x, y, type = "area") +#' +#' # Same result with type_area() +#' tinyplot(x, y, type = type_area()) +#' +#' # Area plots are often used for time series charts +#' tinyplot(AirPassengers, type = "area") +#' @export type_ribbon = function() { out = list( draw = draw_ribbon(), diff --git a/R/type_segments.R b/R/type_segments.R index c75624ee..3dc8d40f 100644 --- a/R/type_segments.R +++ b/R/type_segments.R @@ -1,3 +1,25 @@ +#' Line segments plot type +#' +#' @description Type function for plotting line segments. +#' +#' @details Contrary to base \code{\link[graphics]{segments}}, line segments in +#' [tinyplot] must be specified using the `xmin`, `ymin`,`xmax`, and `ymax` +#' arguments. +#' +#' @examples +#' # "segments" type convenience character string +#' tinyplot( +#' xmin = c(0,.1), ymin = c(.2,1), xmax = c(1,.9), ymax = c(.75,0), +#' type = "segments" +#' ) +#' +#' # Same result with type_segments() +#' tinyplot( +#' xmin = c(0,.1), ymin = c(.2,1), xmax = c(1,.9), ymax = c(.75,0), +#' type = type_segments() +#' ) +#' +#' @export type_segments = function() { out = list( draw = draw_segments(), diff --git a/R/type_spline.R b/R/type_spline.R index 66771c27..332db948 100644 --- a/R/type_spline.R +++ b/R/type_spline.R @@ -1,10 +1,11 @@ -#' Spline type +#' Spline plot type #' #' @description Type function for plotting a cubic (or Hermite) spline interpolation. -#' Arguments are passed to \code{\link[stats]{spline}}; see for default argument -#' values. +#' Arguments are passed to \code{\link[stats]{spline}}; see this latter function +#' for default argument values. #' #' @inheritParams stats::spline +#' @inherit stats::spline details #' @importFrom stats spline #' @examples #' # "spline" type convenience string diff --git a/altdoc/quarto_website.yml b/altdoc/quarto_website.yml index f47064a2..4e990550 100644 --- a/altdoc/quarto_website.yml +++ b/altdoc/quarto_website.yml @@ -15,13 +15,71 @@ website: contents: - text: Home file: index.qmd - - text: Tutorial - file: vignettes/intro_tutorial.qmd - - text: Plot types - file: vignettes/type.qmd - - text: Gallery - file: vignettes/gallery.qmd - - section: $ALTDOC_MAN_BLOCK + - section: Tutorials + contents: + - text: Introduction + file: vignettes/introduction.qmd + - text: Plot types + file: vignettes/types.qmd + - text: Gallery + file: vignettes/gallery.qmd + # - section: $ALTDOC_MAN_BLOCK + - section: Reference + contents: + - section: Plotting functions + contents: + - text: draw_legend + file: man/draw_legend.qmd + - text: tinyplot + file: man/tinyplot.qmd + - section: Plot types + contents: + # + - section: Shapes + contents: + - text: type_area, type_ribbon + file: man/type_ribbon.qmd + - text: type_errorbar, type_pointrange + file: man/type_errorbar.qmd + - text: type_lines + file: man/type_lines.qmd + - text: type_points + file: man/type_points.qmd + - text: type_polygon + file: man/type_polygon.qmd + - text: type_polypath + file: man/type_polypath.qmd + - text: type_rect + file: man/type_rect.qmd + - text: type_segments + file: man/type_segments.qmd + # + - section: Visualizations + contents: + - text: type_boxplot + file: man/type_boxplot.qmd + - text: type_histogram + file: man/type_histogram.qmd + - text: type_jitter + file: man/type_jitter.qmd + # + - section: Models + contents: + - text: type_glm + file: man/type_glm.qmd + - text: type_loess + file: man/type_loess.qmd + - text: type_lm + file: man/type_lm.qmd + - text: type_spline + file: man/type_spline.qmd + # + - section: Options + contents: + - text: tpar + file: man/tpar.qmd + - text: get_saved_par + file: man/get_saved_par.qmd - text: News file: $ALTDOC_NEWS - text: Changelog diff --git a/man/type_boxplot.Rd b/man/type_boxplot.Rd index 19c0d73b..71c91824 100644 --- a/man/type_boxplot.Rd +++ b/man/type_boxplot.Rd @@ -49,5 +49,21 @@ type_boxplot( width.} } \description{ -Boxplot type +Type function for producing box-and-whisker plots. +Arguments are passed to \code{\link[graphics]{boxplot}}, although \code{tinyplot} +scaffolding allows added functionality such as grouping and faceting. +} +\examples{ +# "boxplot" type convenience string +tinyplot(count ~ spray, data = InsectSprays, type = "boxplot") + +# Note: Specifying the type here is redundant. Like base plot, tinyplot +# automatically produces a boxplot if x is a factor and y is numeric +tinyplot(count ~ spray, data = InsectSprays) + +# Use `type_boxplot()` to pass extra arguments for customization +tinyplot( + count ~ spray, data = InsectSprays, lty = 1, + type = type_boxplot(boxwex = 0.3, staplewex = 0, outline = FALSE) +) } diff --git a/man/type_errorbar.Rd b/man/type_errorbar.Rd index 344a84df..4a3e8fd1 100644 --- a/man/type_errorbar.Rd +++ b/man/type_errorbar.Rd @@ -1,14 +1,44 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/type_errorbar.R +% Please edit documentation in R/type_errorbar.R, R/type_pointrange.R \name{type_errorbar} \alias{type_errorbar} -\title{Error bars type} +\alias{type_pointrange} +\title{Error bar and pointrange plot types} \usage{ type_errorbar(length = 0.05) + +type_pointrange() } \arguments{ \item{length}{length of the edges of the arrow head (in inches).} } \description{ -Error bars type +Type function(s) for producing error bar and pointrange plots. +} +\examples{ +mod = lm(Sepal.Length ~ 0 + Sepal.Width * Species, iris) +mod = lm(mpg ~ wt * factor(am), mtcars) +coefs = data.frame(names(coef(mod)), coef(mod), confint(mod)) +colnames(coefs) = c("term", "est", "lwr", "upr") + +op = tpar(pch = 19) + +# "errorbar" and "pointrange" type convenience strings +with( + coefs, + tinyplot(x = term, y = est, ymin = lwr, ymax = upr, type = "errorbar") +) +with( + coefs, + tinyplot(x = term, y = est, ymin = lwr, ymax = upr, type = "pointrange") +) + +# Use `type_errorbar()` to pass extra arguments for customization +with( + coefs, + tinyplot(x = term, y = est, ymin = lwr, ymax = upr, type = type_errorbar(length = 0.2)) +) + +tpar(op) + } diff --git a/man/type_glm.Rd b/man/type_glm.Rd index 59247e1f..e9094f16 100644 --- a/man/type_glm.Rd +++ b/man/type_glm.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/type_glm.R \name{type_glm} \alias{type_glm} -\title{GLM type} +\title{Generalized linear model plot type} \usage{ type_glm(family = "gaussian", se = TRUE, level = 0.95, type = "response") } @@ -22,5 +22,13 @@ type_glm(family = "gaussian", se = TRUE, level = 0.95, type = "response") extract from the fitted model object. Can be abbreviated.} } \description{ -GLM type +Type function for plotting a generalized model fit. +Arguments are passed to \code{\link[stats]{glm}}. +} +\examples{ +# "glm" type convenience string +tinyplot(am ~ mpg, data = mtcars, type = "glm") + +# Use `type_glm()` to pass extra arguments for customization +tinyplot(am ~ mpg, data = mtcars, type = type_glm(family = "binomial")) } diff --git a/man/type_histogram.Rd b/man/type_histogram.Rd index d9c40fe3..9d032277 100644 --- a/man/type_histogram.Rd +++ b/man/type_histogram.Rd @@ -3,7 +3,7 @@ \name{type_histogram} \alias{type_histogram} \alias{type_hist} -\title{Histogram type} +\title{Histogram plot type} \usage{ type_histogram(breaks = "Sturges") @@ -28,3 +28,10 @@ available memory). Type function for histogram plots. \code{type_hist} is an alias for \code{type_histogram}. } +\examples{ +# "histogram"/"hist" type convenience string(s) +tinyplot(Nile, type = "histogram") + +# Use `type_histogram()` to pass extra arguments for customization +tinyplot(Nile, type = type_histogram(breaks = 30)) +} diff --git a/man/type_jitter.Rd b/man/type_jitter.Rd index bb6a3b02..0f71f7d5 100644 --- a/man/type_jitter.Rd +++ b/man/type_jitter.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/type_jitter.R \name{type_jitter} \alias{type_jitter} -\title{Jittered points type} +\title{Jittered points plot type} \usage{ type_jitter(factor = 1, amount = NULL) } @@ -16,5 +16,29 @@ type_jitter(factor = 1, amount = NULL) the smallest difference between \code{x} values.} } \description{ -Jittered points type +Type function for plotting jittered points. +Arguments are passed to \code{\link[base]{jitter}}. +} +\details{ +The result, say \code{r}, is \code{r <- x + runif(n, -a, a)} + where \code{n <- length(x)} and \code{a} is the \code{amount} + argument (if specified). + + Let \code{z <- max(x) - min(x)} (assuming the usual case). + The amount \code{a} to be added is either provided as \emph{positive} + argument \code{amount} or otherwise computed from \code{z}, as + follows: + + If \code{amount == 0}, we set \code{a <- factor * z/50} (same as S). + + If \code{amount} is \code{NULL} (\emph{default}), we set + \code{a <- factor * d/5} where \emph{d} is the smallest + difference between adjacent unique (apart from fuzz) \code{x} values. +} +\examples{ +# "jitter" type convenience string +tinyplot(Sepal.Length ~ Species, data = iris, type = "jitter") + +# Use `type_jitter()` to pass extra arguments for customization +tinyplot(Sepal.Length ~ Species, data = iris, type = type_jitter(factor = 0.5)) } diff --git a/man/type_lines.Rd b/man/type_lines.Rd new file mode 100644 index 00000000..8e2ee6c0 --- /dev/null +++ b/man/type_lines.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/type_lines.R +\name{type_lines} +\alias{type_lines} +\title{Lines plot type} +\usage{ +type_lines(type = "l") +} +\arguments{ +\item{type}{1-character string giving the type of plot desired. The + following values are possible, for details, see \code{\link[graphics]{plot}}: + \code{"p"} for points, \code{"l"} for lines, + \code{"b"} for both points and lines, + \code{"c"} for empty points joined by lines, + \code{"o"} for overplotted points and lines, + \code{"s"} and \code{"S"} for stair steps and + \code{"h"} for histogram-like vertical lines. Finally, + \code{"n"} does not produce any points or lines.} +} +\description{ +Type function for plotting lines. +} +\examples{ +# "l" type convenience character string +tinyplot(circumference ~ age | Tree, data = Orange, type = "l") + +# Use `type_lines()` to pass extra arguments for customization +tinyplot(circumference ~ age | Tree, data = Orange, type = type_lines(type = "s")) + +} diff --git a/man/type_lm.Rd b/man/type_lm.Rd index d21a0c7d..edda21f5 100644 --- a/man/type_lm.Rd +++ b/man/type_lm.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/type_lm.R \name{type_lm} \alias{type_lm} -\title{LM type} +\title{Linear model plot type} \usage{ type_lm(se = TRUE, level = 0.95) } @@ -12,5 +12,13 @@ type_lm(se = TRUE, level = 0.95) \item{level}{the confidence level required.} } \description{ -LM type +Type function for plotting a linear model fit. +Arguments are passed to \code{\link[stats]{lm}}. +} +\examples{ +# "lm" type convenience string +tinyplot(dist ~ speed, data = cars, type = "lm") + +# Use `type_lm()` to pass extra arguments for customization +tinyplot(dist ~ speed, data = cars, type = type_lm(level = 0.9)) } diff --git a/man/type_loess.Rd b/man/type_loess.Rd index 64578d74..a7716f71 100644 --- a/man/type_loess.Rd +++ b/man/type_loess.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/type_loess.R \name{type_loess} \alias{type_loess} -\title{Loess type} +\title{Local polynomial regression plot type} \usage{ type_loess( span = 0.75, diff --git a/man/type_points.Rd b/man/type_points.Rd new file mode 100644 index 00000000..783980de --- /dev/null +++ b/man/type_points.Rd @@ -0,0 +1,23 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/type_points.R +\name{type_points} +\alias{type_points} +\title{Points plot type} +\usage{ +type_points() +} +\description{ +Type function for plotting points, i.e. a scatter plot. +} +\examples{ +# "p" type convenience character string +tinyplot(dist ~ speed, data = cars, type = "p") + +# Same result with type_points() +tinyplot(dist ~ speed, data = cars, type = type_points()) + +# Note: Specifying the type here is redundant. Like base plot, tinyplot +# automatically produces a scatter plot if x and y are numeric +tinyplot(dist ~ speed, data = cars) + +} diff --git a/man/type_polygon.Rd b/man/type_polygon.Rd new file mode 100644 index 00000000..ffcd7661 --- /dev/null +++ b/man/type_polygon.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/type_polygon.R +\name{type_polygon} +\alias{type_polygon} +\title{Polygon plot type} +\usage{ +type_polygon(density = NULL, angle = 45) +} +\arguments{ +\item{density}{the density of shading lines, in lines per inch. The + default value of \code{NULL} means that no shading lines are drawn. + A zero value of \code{density} means no shading nor filling whereas + negative values and \code{NA} suppress shading (and so allow + color filling).} + +\item{angle}{the slope of shading lines, given as an angle + in degrees (counter-clockwise).} +} +\description{ +Type function for plotting polygons. +Arguments are passed to \code{\link[graphics]{polygon}}. +} +\examples{ +# "polygon" type convenience character string +tinyplot(1:9, c(2,1,2,1,NA,2,1,2,1), type = "polygon") + +# Use `type_polygon()` to pass extra arguments for customization +tinyplot(1:9, c(2,1,2,1,NA,2,1,2,1), type = type_polygon(density = c(10, 20))) + +} diff --git a/man/type_polypath.Rd b/man/type_polypath.Rd index 1674dbcf..0e93f4f2 100644 --- a/man/type_polypath.Rd +++ b/man/type_polypath.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/type_polypath.R \name{type_polypath} \alias{type_polypath} -\title{Polypath type} +\title{Polypath polygon type} \usage{ type_polypath(rule = "winding") } @@ -11,5 +11,21 @@ type_polypath(rule = "winding") \code{"winding"} or \code{"evenodd"}.} } \description{ -Polypath type +Type function for plotting polygons. +Arguments are passed to \code{\link[graphics]{polypath}}. +} +\examples{ +# "polypath" type convenience character string +tinyplot( + c(.1, .1, .6, .6, NA, .4, .4, .9, .9), + c(.1, .6, .6, .1, NA, .4, .9, .9, .4), + type = "polypath", fill = "grey" +) + +# Use `type_polypath()` to pass extra arguments for customization +tinyplot( + c(.1, .1, .6, .6, NA, .4, .4, .9, .9), + c(.1, .6, .6, .1, NA, .4, .9, .9, .4), + type = type_polypath(rule = "evenodd"), fill = "grey" +) } diff --git a/man/type_rect.Rd b/man/type_rect.Rd new file mode 100644 index 00000000..26e3f06e --- /dev/null +++ b/man/type_rect.Rd @@ -0,0 +1,34 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/type_rect.R +\name{type_rect} +\alias{type_rect} +\title{Rectangle plot type} +\usage{ +type_rect() +} +\description{ +Type function for plotting rectangles. +} +\details{ +Contrary to base \code{\link[graphics]{rect}}, rectangles in +\link{tinyplot} must be specified using the \code{xmin}, \code{ymin},\code{xmax}, and \code{ymax} +arguments. +} +\examples{ +i = 4*(0:10) + +# "rect" type convenience character string +tinyplot( + xmin = 100+i, ymin = 300+i, xmax = 150+i, ymax = 380+i, + by = i, fill = 0.2, + type = "rect" +) + +# Same result with type_rect() +tinyplot( + xmin = 100+i, ymin = 300+i, xmax = 150+i, ymax = 380+i, + by = i, fill = 0.2, + type = type_rect() +) + +} diff --git a/man/type_ribbon.Rd b/man/type_ribbon.Rd new file mode 100644 index 00000000..35d18a21 --- /dev/null +++ b/man/type_ribbon.Rd @@ -0,0 +1,44 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/type_area.R, R/type_ribbon.R +\name{type_area} +\alias{type_area} +\alias{type_ribbon} +\title{Ribbon and area plot types} +\usage{ +type_area() + +type_ribbon() +} +\description{ +Type constructor functions for producing polygon ribbons, which +define a \code{y} interval (usually spanning from \code{ymin} to \code{ymax}) for each +\code{x} value. Area plots are a special case of ribbon plot where \code{ymin} is +set to 0 and \code{ymax} is set to \code{y}. +} +\examples{ +x = 1:100/10 +y = sin(x) + +# +## Ribbon plots + +# "ribbon" convenience string +tinyplot(x = x, ymin = y-1, ymax = y+1, type = "ribbon") +# Same result with type_ribbon() +tinyplot(x = x, ymin = y-1, ymax = y+1, type = type_ribbon()) + +# y will be added as a line if it is specified +tinyplot(x = x, y = y, ymin = y-1, ymax = y+1, type = "ribbon") + +# +## Area plots + +# "area" type convenience string +tinyplot(x, y, type = "area") + +# Same result with type_area() +tinyplot(x, y, type = type_area()) + +# Area plots are often used for time series charts +tinyplot(AirPassengers, type = "area") +} diff --git a/man/type_segments.Rd b/man/type_segments.Rd new file mode 100644 index 00000000..38c96083 --- /dev/null +++ b/man/type_segments.Rd @@ -0,0 +1,30 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/type_segments.R +\name{type_segments} +\alias{type_segments} +\title{Line segments plot type} +\usage{ +type_segments() +} +\description{ +Type function for plotting line segments. +} +\details{ +Contrary to base \code{\link[graphics]{segments}}, line segments in +\link{tinyplot} must be specified using the \code{xmin}, \code{ymin},\code{xmax}, and \code{ymax} +arguments. +} +\examples{ +# "segments" type convenience character string +tinyplot( + xmin = c(0,.1), ymin = c(.2,1), xmax = c(1,.9), ymax = c(.75,0), + type = "segments" +) + +# Same result with type_segments() +tinyplot( + xmin = c(0,.1), ymin = c(.2,1), xmax = c(1,.9), ymax = c(.75,0), + type = type_segments() +) + +} diff --git a/man/type_spline.Rd b/man/type_spline.Rd index 2b18fdeb..7c4468c6 100644 --- a/man/type_spline.Rd +++ b/man/type_spline.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/type_spline.R \name{type_spline} \alias{type_spline} -\title{Spline type} +\title{Spline plot type} \usage{ type_spline( n = NULL, @@ -36,8 +36,34 @@ type_spline( } \description{ Type function for plotting a cubic (or Hermite) spline interpolation. -Arguments are passed to \code{\link[stats]{spline}}; see for default argument -values. +Arguments are passed to \code{\link[stats]{spline}}; see this latter function +for default argument values. +} +\details{ +The inputs can contain missing values which are deleted, so at least + one complete \code{(x, y)} pair is required. + If \code{method = "fmm"}, the spline used is that of + Forsythe, Malcolm and Moler + (an exact cubic is fitted through the four points at each + end of the data, and this is used to determine the end conditions). + Natural splines are used when \code{method = "natural"}, and periodic + splines when \code{method = "periodic"}. + + The method \code{"monoH.FC"} computes a \emph{monotone} Hermite spline + according to the method of Fritsch and Carlson. It does so by + determining slopes such that the Hermite spline, determined by + \eqn{(x_i,y_i,m_i)}{(x[i],y[i],m[i])}, is monotone (increasing or + decreasing) \bold{iff} the data are. + + Method \code{"hyman"} computes a \emph{monotone} cubic spline using + Hyman filtering of an \code{method = "fmm"} fit for strictly monotonic + inputs. + + These interpolation splines can also be used for extrapolation, that is + prediction at points outside the range of \code{x}. Extrapolation + makes little sense for \code{method = "fmm"}; for natural splines it + is linear using the slope of the interpolating curve at the nearest + data point. } \examples{ # "spline" type convenience string diff --git a/vignettes/intro_tutorial.qmd b/vignettes/introduction.qmd similarity index 100% rename from vignettes/intro_tutorial.qmd rename to vignettes/introduction.qmd diff --git a/vignettes/type.qmd b/vignettes/type.qmd deleted file mode 100644 index cd1913fe..00000000 --- a/vignettes/type.qmd +++ /dev/null @@ -1,191 +0,0 @@ ---- -title: "Plot types" ---- - -`tinyplot` is a lightweight extension of R's base plotting system, designed to simplify and enhance data visualization. One of its key features is the `type` argument, which allows you to specify different types of plots easily. This tutorial will guide you through the various plot types available in `tinyplot`, demonstrating how to use the `type` argument to create a wide range of visualizations. - -We will consider three categories of plot types: - -1. Base types -2. `tinyplot` types -3. Custom types - -We will use the built-in `airquality` dataset for our examples: - -```{r} -library(tinyplot) - -aq = transform( - airquality, - Month = factor(Month, labels = month.abb[unique(Month)]), - Hot = Temp > median(Temp) -) -``` - -# Base types - -The `type` argument in `tinyplot` supports all the standard plot types from base R's `plot` function. These are specified using single-character strings. - -The default plot type is `"p"`, which creates a scatter plot of points. - -```{r} -tinyplot(Temp ~ Day | Month, data = aq, type = "p", main = "Points") -``` - -Use `"l"` to connect data points with lines. - -```{r} -tinyplot(Temp ~ Day | Month, data = aq, type = "l", main = "Lines") -``` - -Other base plot types supported as single-character strings: - -* `b` (Points and Lines): Combines points and lines in the plot. -* `c` (Empty Points Joined by Lines): Plots empty points connected by lines. -* `o` (Overplotted Points and Lines): Overlaps points and lines. -* `s` and `S` (Stair Steps): Creates a step plot. -* `h` (Histogram-like Vertical Lines): Plots vertical lines resembling a histogram. -* `n` (Empty Plot): Creates an empty plot frame without data. - -# `tinyplot` types - -Beyond the base types, `tinyplot` introduces additional plot types for more advanced visualizations. - -Models: - -- `loess`, `type_loess()`: Local regression curve. -- `lm`, `type_lm()`: Linear regression line. -- `glm`, `type_glm()`: Generalized linear model fit. - -Shapes: - -- `segments`: Draws line segments between pairs of points. -- `polygon`: Draws filled polygons. -- `errorbar`: Adds error bars to points; requires ymin and ymax. -- `pointrange`: Combines points with error bars. -- `ribbon`: Creates a filled area between ymin and ymax. -- `area`: Plots the area under the curve from y = 0 to y = f(x). -- `rect`: Draws rectangles; requires `xmin`, `xmax`, `ymin`, and `ymax`. - -Visualizations: - -- `jitter` / `type_jitter()`: Jittered points. -- `boxplot` / `type_boxplot()`: Creates a box-and-whisker plot. -- `histogram` / `type_histogram()`: Creates a histogram of a single variable. -- `density`: Plots the density estimate of a variable. - -There are two main ways to use `tinyplot` types. First, we can specify the type directly using a string shortcut in the `type` argument, such as `type="boxplot"`. - -Second, many `tinyplot` types are implemented by a `type_*()` function which includes arguments that allow us to customize the plot further. For example, the `type_jitter()` function includes arguments to control the amount of jittering, and the `type_glm()` includes an argument to control the width of the confidence interval to display. To see what arguments are available for each type, simply consult the type-specific documentation: - -```r -?type_jitter -?type_glm -``` - -For example, we can add noise to data points using the `"jitter"` type. This allows us to avoid overplotting and can be useful to visualize discrete variables. On the left, we use the string shortcut with default settings. On the right, we use the `type_jitter()` function to select a smaller amount of jittering: - -```{r} -#| layout-ncol: 2 -tinyplot( - Temp ~ Month, data = aq, main = "Default jittering", - type = "jitter" -) - -tinyplot( - Temp ~ Month, data = aq, main = "Modest jittering", - type = type_jitter(amount = 0.05) -) -``` - -In this example, we use `type_glm()` to fit a logit regression model to the data, and display different confidence interval sizes: - -```{r} -#| layout-ncol: 2 -tinyplot( - Hot ~ Wind, data = aq, main = "Logit with 95% interval", - type = type_glm(family = "binomial") -) - -tinyplot( - Hot ~ Wind, data = aq, main = "Logit with 50% interval", - type = type_glm(family = "binomial", level = 0.5) -) -``` - -All `tinyplot` types should support grouping and faceting: - -```{r} -tinyplot(Temp ~ Wind | Month, data = aq, facet = "by", type = "lm") -``` - -# Custom types - -It is easy to add custom types to `tinyplot`. Users who need highly customized plots, or developers who want to add support to their package or functions, only need to define three simple functions: `data_typename()`, `draw_typename()`, and `type_typename()`. - -In this section, we explain the role of each of these functions and present a minimalist example of a custom type. Interested readers may refer to [the `tinyplot` source code](https://github.com/grantmcdermott/tinyplot) to see many more examples, since each `tinyplot` type is itself implemented as a custom type. - -The three functions that we need to define for a new type are: - -1. `data_*()`: Function factory. - - Accepts a list of internal objects - - Inputs must include `...` - - `datapoints` Is the most important object. It is a data frame with the datapoints to plot. - - Other objects that can be modified by `data_*()` include: `by`, `facet`, `ylab`, `palette` - - Returns a named list with modified versions of those objects. -2. `draw_*()`: Function factory. - - Accepts information about data point values and aesthetics. - - Inputs must include `...` - - The `i` prefix in argument names indicates that we are operating on a subgroup of the data, identified by `facet` or using the `|` operator in a formula. - - Available arguments are: `ibg`, `icol`, `ilty`, `ilwd`, `ipch`, `ix`, `ixmax`, `ixmin`, `iy`, `iymax`, `iymin`, `cex`, `dots`, `type`, `x_by`, `i`, `facet_by`, `by_data`, `facet_data`, `flip` - - Returns a function which can call base R to draw the plot. -3. `type_*()`: A wrapper function that returns a named list with three elements: - - `draw` - - `data` - - `name` - -Here is a minimalist example of a custom type that logs both `x` and `y` and plots lines: - -```{r} -type_log = function(base = exp(1)) { - - data_log = function() { - fun = function(datapoints, ...) { - datapoints$x = log(datapoints$x, base = base) - datapoints$y = log(datapoints$y, base = base) - datapoints = datapoints[order(datapoints$x), ] - return(list(datapoints = datapoints, ...)) - } - return(fun) - } - - draw_log = function() { - fun = function(ix, iy, icol, ...) { - points( - x = ix, - y = iy, - col = icol - ) - } - return(fun) - } - - out = list( - draw = draw_log(), - data = data_log(), - name = "log" - ) - class(out) = "tinyplot_type" - return(out) -} - -tinyplot(mpg ~ wt | factor(am), data = mtcars, - type = "p", main = "Raw") - -tinyplot(mpg ~ wt | factor(am), data = mtcars, - type = type_log(), main = "Ln") - -tinyplot(mpg ~ wt | factor(am), data = mtcars, - type = type_log(base = 10), main = "Log 10") -``` - diff --git a/vignettes/types.qmd b/vignettes/types.qmd new file mode 100644 index 00000000..166aca1c --- /dev/null +++ b/vignettes/types.qmd @@ -0,0 +1,220 @@ +--- +title: "Plot types" +--- + +**tinyplot** is a lightweight extension of R's base plotting system, designed to +simplify and enhance data visualization. One of its key features is the `type` +argument, which allows you to specify different types of plots easily. This +tutorial will guide you through the various plot types available in +**tinyplot**, demonstrating how to use the `type` argument to create a wide +range of visualizations. + +We will consider three categories of plot types: + +1. Base types +2. **tinyplot** types +3. Custom types + +We will use the built-in `airquality` dataset for our examples: + +```{r} +library(tinyplot) + +aq = transform( + airquality, + Month = factor(Month, labels = month.abb[unique(Month)]), + Hot = Temp > median(Temp) +) +``` + +## Base types + +The `type` argument in `tinyplot` supports all the standard plot types from +base R's `plot` function. These are specified using single-character strings. + +- `"p"` (Points): Produces a scatter plot of points. This is (usually) the default plot type. +- `"l"` (Lines): Produces a line plot. +- `"b"` (Points and Lines): Combines points and lines in same the plot. +- `"c"` (Empty Points Joined by Lines): Plots empty points connected by lines. +- `"o"` (Overplotted Points and Lines): Overlaps points and lines. +- `"s"` and `"S"` (Stair Steps): Creates a step plot. +- `"h"` (Histogram-like Vertical Lines): Plots vertical lines resembling a histogram. +- `"n"` (Empty Plot): Creates an empty plot frame without data. + +For example, we can use `"b"` to create a plot with combined points and lines. + +```{r} +tinyplot(Temp ~ Day | Month, data = aq, type = "b", main = "Points and lines") +``` + +## tinyplot types + +Beyond the base types, **tinyplot** introduces additional plot types for more +advanced visualizations. Each of these additional types are available either as +a convenience string (with default behaviour) or a companion `type_*()` function +(with options for customized behaviour). + +Models: + +- `"loess"` / `type_loess()`: Local regression curve. +- `"lm"` / `type_lm()`: Linear regression line. +- `"glm"` / `type_glm()`: Generalized linear model fit. +- `"spline"` / `type_spline()`: Cubic (or Hermite) spline interpolation. + +Shapes: + +- `area` / `type_area()`: Plots the area under the curve from `y` = 0 to `y` = f(`x`). +- `rect` / `type_area()`: Draws rectangles; requires `xmin`, `xmax`, `ymin`, and `ymax`. +- `ribbon` / `type_ribbon()`: Creates a filled area between `ymin` and `ymax`. +- `"segments"` / `type_segements()`: Draws line segments between pairs of points. +- `"polygon"` / `type_polygon()`: Draws polygons. +- `"polypath"` / `type_polypath()`: Draws a path whose vertices are given in `x` and `y`. +- `"errorbar"` / `type_errorbar()`: Adds error bars to points; requires `ymin` and `ymax`. +- `pointrange` / `type_pointrange`: Combines points with error bars. + +Visualizations: + +- `"jitter"` / `type_jitter()`: Jittered points. +- `"boxplot"` / `type_boxplot()`: Creates a box-and-whisker plot. +- `"histogram"` / `type_histogram()`: Creates a histogram of a single variable. +- `"density"`: Plots the density estimate of a variable. + +To see the difference between the convenience strings and their respective +companion `type_*` functions, let's quickly walk through two examples. + +**Example 1: jittering.** We can add noise to data points using jittering. This +allows us to avoid overplotting and can be useful to visualize discrete +variables. On the left, we use the `"jitter` string shortcut with default +settings. On the right, we use the `type_jitter()` function to reduce the amount +of jittering. + +```{r} +#| layout-ncol: 2 +tinyplot( + Temp ~ Month, data = aq, main = "Default jittering", + type = "jitter" +) + +tinyplot( + Temp ~ Month, data = aq, main = "Modest jittering", + type = type_jitter(amount = 0.05) +) +``` + +**Example 2: Logit fit.** In this example, we use `type_glm()` to fit a logistic +regression model to the data, but with different confidence intervals.^[Note: If +we simply specified the `"glm"` convenience string on its own, we'd get a linear +fit since the default family is `gaussian`.] + +```{r} +#| layout-ncol: 2 +tinyplot( + Hot ~ Wind, data = aq, main = "Logit with 95% interval", + type = type_glm(family = "binomial") +) + +tinyplot( + Hot ~ Wind, data = aq, main = "Logit with 50% interval", + type = type_glm(family = "binomial", level = 0.5) +) +``` + +To see what arguments are available for each type, simply consult the +type-specific documentation. + +```r +?type_jitter +?type_glm +# etc +``` + +Finally, please note that all **tinyplot** types support grouping and faceting. + +```{r} +tinyplot(Temp ~ Wind | Month, data = aq, facet = "by", type = "lm") +``` + +## Custom types + +It is easy to add custom types to **tinyplot**. Users who need highly customized +plots, or developers who want to add support to their package or functions, only +need to define three simple functions: `data_typename()`, `draw_typename()`, and +`type_typename()`. + +In this section, we explain the role of each of these functions and present a +minimalist example of a custom type. Interested readers may refer to +[the **tinyplot** source code](https://github.com/grantmcdermott/tinyplot) +to see many more examples, since each **tinyplot** type is itself implemented as a +custom type. + +The three functions that we need to define for a new type are: + +1. `data_*()`: Function factory. + - Accepts a list of internal objects + - Inputs must include `...` + - `datapoints` Is the most important object. It is a data frame with the datapoints to plot. + - Other objects that can be modified by `data_*()` include: `by`, `facet`, `ylab`, `palette` + - Returns a named list with modified versions of those objects. +2. `draw_*()`: Function factory. + - Accepts information about data point values and aesthetics. + - Inputs must include `...` + - The `i` prefix in argument names indicates that we are operating on a subgroup of the data, identified by `facet` or using the `|` operator in a formula. + - Available arguments are: `ibg`, `icol`, `ilty`, `ilwd`, `ipch`, `ix`, `ixmax`, `ixmin`, `iy`, `iymax`, `iymin`, `cex`, `dots`, `type`, `x_by`, `i`, `facet_by`, `by_data`, `facet_data`, `flip` + - Returns a function which can call base R to draw the plot. +3. `type_*()`: A wrapper function that returns a named list with three elements: + - `draw` + - `data` + - `name` + +Here is a minimalist example of a custom type that logs both `x` and `y` and +plots lines. + +```{r} +#| layout-ncol: 2 +type_log = function(base = exp(1)) { + + data_log = function() { + fun = function(datapoints, ...) { + datapoints$x = log(datapoints$x, base = base) + datapoints$y = log(datapoints$y, base = base) + datapoints = datapoints[order(datapoints$x), ] + return(list(datapoints = datapoints, ...)) + } + return(fun) + } + + draw_log = function() { + fun = function(ix, iy, icol, ...) { + points( + x = ix, + y = iy, + col = icol + ) + } + return(fun) + } + + out = list( + draw = draw_log(), + data = data_log(), + name = "log" + ) + class(out) = "tinyplot_type" + return(out) +} + +tinyplot(mpg ~ wt | factor(am), data = mtcars, + type = type_log(), main = "Ln") + +tinyplot(mpg ~ wt | factor(am), data = mtcars, + type = type_log(base = 10), main = "Log 10") +``` + +To underscore what we said above, the **tinyplot** +[source code](https://github.com/grantmcdermott/tinyplot/tree/main/R) +contains many examples of type constructor functions that should provide a +helpful starting point for custom plot types. Failing that, the **tinyplot** +team are always happy to help guide users on how to create their own types and +re-purpose existing **tinyplot** code. Just let us know by +[raising an issue](https://github.com/grantmcdermott/tinyplot/issues) +on our GitHub repo.