diff --git a/.Rbuildignore b/.Rbuildignore index 0b3fa48..a64582f 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -6,3 +6,5 @@ ^codecov\.yml$ ^.*\.Rproj$ ^\.Rproj\.user$ +^_pkgdown\.yml$ +^docs$ diff --git a/DESCRIPTION b/DESCRIPTION index 48fc48c..24275b0 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -18,10 +18,11 @@ Imports: ggplot2 (>= 2.2.1), extrafont Suggests: - spelling, tufte, knitr, rmarkdown, + scales, + spelling, testthat, covr Authors@R: c(person("Jeffrey", "Arnold", role = c("aut", "cre"), email = "jeffrey.arnold@gmail.com", diff --git a/NAMESPACE b/NAMESPACE index 4545af5..dd9e146 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -1,25 +1,22 @@ # Generated by roxygen2: do not edit by hand +export(GeomQuartilePlot) export(GeomRangeFrame) -export(GeomTufteboxplot) export(StatFivenumber) -export(extended_range_breaks) -export(extended_range_breaks_) export(font_et) +export(geom_quartileplot) export(geom_rangeframe) -export(geom_tufteboxplot) -export(import_et_book) -export(smart_digits) -export(smart_digits_format) +export(import_ggtufte_fonts) +export(range_breaks) export(stat_fivenumber) export(theme_tufte) -export(tufte_theme_fonts) importFrom(ggplot2,Geom) importFrom(ggplot2,GeomPoint) importFrom(ggplot2,GeomSegment) importFrom(ggplot2,StatSummaryBin) importFrom(ggplot2,aes) importFrom(ggplot2,element_blank) +importFrom(ggplot2,element_text) importFrom(ggplot2,ggproto) importFrom(ggplot2,ggproto_parent) importFrom(ggplot2,layer) diff --git a/R/et-book.R b/R/et-book.R index dac826e..c56ce5e 100644 --- a/R/et-book.R +++ b/R/et-book.R @@ -15,7 +15,7 @@ #' @references #' @source #' @export -import_et_book <- function() { +import_ggtufte_fonts <- function() { # function adapted from hbrthemes::import_roboto_condensed font_dir <- system.file("fonts", package = "ggtufte") @@ -41,6 +41,10 @@ import_et_book <- function() { #' - `"ETBembo BoldLF"`: Bold (lining figures) #' - `"ETBembo DisplayItalic"`: Display Italic (oldstyle figures) #' +#' For headings, the sans serif font, Gill Sans is used. +#' Since there is no Gill Sans variant with an open license, the similar +#' Lato font is included with this package. +#' #' @md #' @title ET Book fonts R variable aliases #' @format length 5 character vector. Values are the @@ -53,4 +57,31 @@ font_et <- c("Roman (line figures)" = "ETBembo RomanLF", "Roman (old-style figures)" = "ETBembo RomanOSF", "Bold (line figures)" = "ETBembo BoldLF", "Semi-bold (old-style figures)" = "ETBembo SemiBoldOSF", - "Display italic" = "ETBembo DisplayItalic") \ No newline at end of file + "Display italic" = "ETBembo DisplayItalic") + +# choose +get_etbembo <- function(italic = FALSE) { + fonttable <- extrafont::fonttable() + if (italic) { + if ("ETBembo DisplayItalic" %in% fonttable[["FullName"]]) { + return("ETBembo DisplayItalic") + } + } else { + if ("ETBembo RomanLF" %in% fonttable[["FullName"]]) { + return("ETBembo RomanLF") + } + } + "Palatino" +} + +# Gill Sans type font +get_gill_sans <- function() { + fallbacks <- c("Gill Sans Nova", "Gill Sans MT", "Gill Sans Std", + "Lato", "sans") + fontlist <- extrafont::fonts() + for (font in fallbacks) { + if (font %in% fontlist) { + return(font) + } + } +} \ No newline at end of file diff --git a/R/geom-tufteboxplot.R b/R/geom-tufteboxplot.R index 099c900..b1a44ac 100644 --- a/R/geom-tufteboxplot.R +++ b/R/geom-tufteboxplot.R @@ -1,131 +1,96 @@ -#' Tufte's Box Plot +#' A box and whisker's plot (in the style of Tufte) #' -#' Edward Tufte's revisions of the box plot as described in -#' \emph{The Visual Display of Quantitative Information}. -#' This functions provides several box plot variants: -#' \itemize{ -#' \item{A point indicating the median, a gap indicating the -#' interquartile range, and lines for whiskers.} -#' \item{An offset line indicating the interquartile range -#' and a gap indicating the median.} -#' \item{A line indicating the interquartile range, -#' a gap indicating the median, and points indicating -#' the minimum and maximum values} -#' \item{A wide line indicating the interquartile range, -#' a gap indicating the median, and lines indicating the minimum and -#' maximum.} -#' } +#' Tufte \emph{The Visual Display of Quantitative Information} (Ch 6) +#' proposes several revisions of the box plot. +#' These variants compactly display the distribution of a continuous variable. +#' It visualises five summary statistics: the median, two hinges (25\% and 75\% quartiles) +#' and two whiskers (minimum, maximum). +#' +#' The statistics are different than \code{\link{geom_boxplot}}. #' #' @section Aesthetics: #' \itemize{ -#' \item x [required] -#' \item y [required] -#' \item colour -#' \item size -#' \item linetype -#' \item shape -#' \item fill -#' \item alpha +#' \item x (required) x coordinate of the line +#' \item upper +#' \item lower +#' \item middle +#' \item ymin +#' \item ymax +#' \item colour (required) +#' \item size thickness of the lines +#' \item linetype types of the lines +#' \item width +#' \item shape shape of the point(s) +#' \item fill fill of the point(s) +#' \item alpha transparency #' } #' #' @references Tufte, Edward R. (2001) The Visual Display of -#' Quantitative Information, Chapter 6. -#' -#' McGill, R., Tukey, J. W. and Larsen, W. A. (1978) Variations of -#' box plots. The American Statistician 32, 12-16. +#' Quantitative Information, Chapter 6. #' #' @seealso \code{\link{geom_boxplot}} #' @inheritParams ggplot2::geom_point -#' @param outlier.colour colour for outlying points -#' @param outlier.shape shape of outlying points -#' @param outlier.size size of outlying points -#' @param outlier.stroke stroke for outlying points -#' @param median.type If \code{'point'}, then the median is represented by a -#' point, and the interquartile range by a gap in the line. If -#' \code{median.type='line'}, then the interquartile range is represented by -#' a line, possibly offset, and the median by a gap in the line. -#' @param whisker.type If \code{'line'}, then whiskers are represented by lines. -#' If \code{'point'}, then whiskers are represented by points at -#' \code{ymin} and \code{ymax}. -#' @param voffset controls the size of the gap in the line representing the -#' median when \code{median.type = 'line'}. This is a fraction of the range -#' of \code{y}. -#' @param hoffset controls how much the interquartile line is offset from the -#' whiskers when \code{median.type = 'line'}. This is a fraction of the -#' range of \code{x}. +#' @seealso \code{\link{geom_boxplot}} and \code{\link{geom_pointrange}}. #' @family geom tufte #' @export #' -#' @example examples/ex-geom_tufteboxplot.R -geom_tufteboxplot <- - function(mapping = NULL, - data = NULL, - stat = "fivenumber", - position = "dodge", - outlier.colour = "black", - outlier.shape = 19, - outlier.size = 1.5, - outlier.stroke = 0.5, - voffset = 0.01, - hoffset = 0.005, - na.rm = FALSE, - show.legend = NA, - inherit.aes = TRUE, - median.type = "point", - whisker.type = "line", - ...) { +#' @example examples/ex-geom_quartileplot.R +geom_quartileplot <- function(mapping = NULL, + data = NULL, + stat = "fivenumber", + position = "dodge", + na.rm = FALSE, + show.legend = NA, + inherit.aes = TRUE, + middle.line = FALSE, + whisker.line = TRUE, + hoffset = 0.01, + fatten = 1, + gapsize = 0.01, + ...) { layer( data = data, mapping = mapping, stat = stat, - geom = GeomTufteboxplot, + geom = GeomQuartilePlot, position = position, show.legend = show.legend, inherit.aes = inherit.aes, params = list( - outlier.colour = outlier.colour, - outlier.shape = outlier.shape, - outlier.size = outlier.size, - outlier.stroke = outlier.stroke, - voffset = voffset, - hoffset = hoffset, - median.type = median.type, - whisker.type = whisker.type, + middle.line = middle.line, + whisker.line = whisker.line, na.rm = na.rm, + hoffset = hoffset, + fatten = fatten, + gapsize = gapsize, ... ) ) } -#' @rdname geom_tufteboxplot +#' @rdname geom_quartileplot #' @usage NULL #' @format NULL #' @export #' @importFrom ggplot2 ggproto_parent aes GeomPoint GeomSegment #' @importFrom grid grobTree -GeomTufteboxplot <- - ggplot2::ggproto("GeomTufteboxplot", +GeomQuartilePlot <- + ggplot2::ggproto("GeomQuartilePlot", ggplot2::GeomBoxplot, setup_data = function(self, data, params) { data <- ggproto_parent(GeomBoxplot, self)$setup_data(data, params) x_range <- diff(range(data$x)) y_range <- max(data$ymax) - min(data$ymin) data$hoffset <- params$hoffset * x_range - data$voffset <- params$voffset * y_range + data$gapsize <- params$gapsize * y_range data }, - draw_group = function(data, panel_scales, coord, fatten = 2, - outlier.colour = "black", outlier.shape = 19, - outlier.size = 1.5, outlier.stroke = 0.5, - varwidth = FALSE, - median.type = c("point", "line"), - whisker.type = c("line", "point"), - hoffset = 0.01, - voffset = 0.01 - ) { - median.type <- match.arg(median.type) - whisker.type <- match.arg(whisker.type) - + draw_group = function(data, panel_scales, coord, + middle.line = FALSE, + whisker.line = TRUE, + hoffset = 0.001, + gapsize = 0.01, + fatten = 1) { common <- data.frame( colour = data$colour, linetype = data$linetype, @@ -135,8 +100,8 @@ GeomTufteboxplot <- group = data$group, stringsAsFactors = FALSE ) - - if (whisker.type == "line") { + # whiskers + if (whisker.line) { whiskers <- data.frame( x = data$x, xend = data$x, @@ -147,9 +112,9 @@ GeomTufteboxplot <- common, stringsAsFactors = FALSE ) - whiskers_grob <- - GeomSegment$draw_panel(whiskers, panel_scales, coord) - } else if (whisker.type == "point") { + whiskers_grob <- GeomSegment$draw_panel(whiskers, panel_scales, + coord) + } else { whiskers <- data.frame( x = data$x, y = c(data$ymin, data$ymax), @@ -158,73 +123,47 @@ GeomTufteboxplot <- common, stringsAsFactors = FALSE ) - whiskers_grob <- - GeomPoint$draw_panel(whiskers, panel_scales, coord) + whiskers_grob <- GeomPoint$draw_panel(whiskers, panel_scales, + coord) } - - if (median.type == "point") { + # middle point + if (middle.line) { middata <- data.frame( - x = data$x, - y = data$middle, - size = data$size * data$width, - alpha = data$alpha, - common, - stringsAsFactors = FALSE - ) - middle_grob <- GeomPoint$draw_panel(middata, panel_scales, coord) - } else if (median.type == "line") { - middata <- data.frame( - y = c(data$upper, data$middle) + c(0, - data$voffset / 2), - yend = c(data$middle, data$lower) + c(data$voffset / 2, 0), + y = c(data$upper, data$middle - 0.5 * data$gapsize), + yend = c(data$middle + 0.5 * data$gapsize, data$lower), x = data$x + data$hoffset, xend = data$x + data$hoffset, - size = data$size * data$width, + size = data$size * fatten, alpha = data$alpha, common, stringsAsFactors = FALSE ) middle_grob <- GeomSegment$draw_panel(middata, panel_scales, coord) - - } - - if (!is.null(data$outliers) && length(data$outliers[[1]] >= 1)) { - outliers <- data.frame( - y = data$outliers[[1]], - x = data$x[1], - colour = outlier.colour %||% data$colour[1], - shape = outlier.shape %||% data$shape[1], - size = outlier.size %||% data$size[1], - stroke = outlier.stroke %||% data$stroke[1], - fill = NA, - alpha = NA, + } else { + middata <- data.frame( + x = data$x, + y = data$middle, + size = data$size * fatten, + alpha = data$alpha, + common, stringsAsFactors = FALSE ) - outliers_grob <- GeomPoint$draw_panel(outliers, panel_scales, - coord) - } else { - outliers_grob <- NULL - } - - ggname("geom_tufteboxplot", + middle_grob <- GeomPoint$draw_panel(middata, panel_scales, coord) } + ggname("geom_quartileplot", grobTree( - outliers_grob, whiskers_grob, middle_grob )) }, draw_legend = ggplot2::draw_key_pointrange, default_aes = ggplot2::aes(weight = 1, - colour = "black", - fill = "grey20", - size = 0.5, - alpha = NA, - shape = 19, - stroke = 0.5, - width = 1, - linetype = "solid", - outlier.colour = "black", - outlier.shape = 19, - outlier.size = 1.5, - outlier.stroke = 0.5) + colour = "black", + fill = "grey20", + size = 0.5, + alpha = NA, + shape = 19, + stroke = 0.5, + width = 1, + linetype = "solid") ) diff --git a/R/extended_range_breaks.R b/R/range_breaks.R similarity index 52% rename from R/extended_range_breaks.R rename to R/range_breaks.R index beea839..d5ba9eb 100644 --- a/R/extended_range_breaks.R +++ b/R/range_breaks.R @@ -1,7 +1,6 @@ # Much of this code is copied from the labeling package. simplicity <- function(q, Q, j, lmin, lmax, lstep) { eps <- .Machine$double.eps * 100 - n <- length(Q) i <- match(q, Q)[1] v <- ifelse( (lmin %% lstep < eps || @@ -14,20 +13,19 @@ simplicity_max <- function(q, Q, j) { n <- length(Q) i <- match(q, Q)[1] v <- 1 - 1 - (i - 1) / (n - 1) - j + v } coverage <- function(dmin, dmax, lmin, lmax) { range <- dmax - dmin - 1 - 0.5 * ( (dmax - lmax) ^ 2 + (dmin - lmin) ^ 2) / ( (0.1 * range) ^ 2) + 1 - 0.5 * ((dmax - lmax) ^ 2 + (dmin - lmin) ^ 2) / ((0.1 * range) ^ 2) } coverage_max <- function(dmin, dmax, span) { range <- dmax - dmin if (span > range) { half <- (span - range) / 2 - 1 - 0.5 * (half ^ 2 + half ^ 2) / ( (0.1 * range) ^ 2) + 1 - 0.5 * (half ^ 2 + half ^ 2) / ((0.1 * range) ^ 2) } else { 1 @@ -51,129 +49,99 @@ legibility <- function(lmin, lmax, lstep) { 1 } - #' Pretty axis breaks inclusive of extreme values #' #' This function returns pretty axis breaks that always include the extreme values of the data. #' This works by calling the extended Wilkinson algorithm (Talbot et. al, 2010), constrained to solutions interior to the data range. #' Then, the minimum and maximum labels are moved to the minimum and maximum of the data range. #' -#' \code{extended_range_breaks} implements the algorithm and returns the break values. -#' \code{scales_extended_range_breaks} uses the conventions of the \pkg{scales} package, and returns a function. -#' -#' @param dmin minimum of the data range -#' @param dmax maximum of the data range +#' @param x Vector of numeric values #' @param n desired number of breaks #' @param Q set of nice numbers #' @param w weights applied to the four optimization components (simplicity, coverage, density, and legibility) -#' @return For \code{extended_range_breaks}, the vector of axis label locations. -#' For \code{scales_extended_range_breaks}, a function which takes a single argument, a vector of data, and returns the vector of axis label locations. +#' @return For \code{range_breaks}, a function which takes a single argument, +#' a vector of data, which returns the vector of axis label locations. #' @references #' Talbot, J., Lin, S., Hanrahan, P. (2010) An Extension of Wilkinson's Algorithm for Positioning Tick Labels on Axes, InfoVis 2010. #' @author Justin Talbot \email{jtalbot@@stanford.edu}, Jeffrey B. Arnold, Baptiste Auguie #' @rdname range_breaks #' @export -extended_range_breaks_ <- function(dmin, dmax, n = 5, - Q = c(1, 5, 2, 2.5, 4, 3), - w = c(0.25, 0.2, 0.5, 0.05)) { - eps <- .Machine$double.eps * 100 - - if (dmin > dmax) { - temp <- dmin - dmin <- dmax - dmax <- temp - } - - if (dmax - dmin < eps) { - #if the range is near the floating point limit, - #let seq generate some equally spaced steps. - return(seq(from = dmin, to = dmax, length.out = n)) - } - - n <- length(Q) - - best <- list() - best$score <- -2 - - j <- 1 - while (j < Inf) { - for (q in Q) { - sm <- simplicity_max(q, Q, j) - - if ( (w[1] * sm + w[2] + w[3] + w[4]) < best$score) { - j <- Inf - break - } - - k <- 2 - while (k < Inf) { - dm <- density_max(k, n) - if ( (w[1] * sm + w[2] + w[3] * dm + w[4]) < best$score) +range_breaks <- function(x, + n = 5, + Q = c(1, 5, 2, 2.5, 4, 3), + w = c(0.25, 0.2, 0.5, 0.05)) { + function(x) { + eps <- .Machine$double.eps * 100 + dmin <- min(x) + dmax <- max(x) + if (dmax - dmin < eps) { + #if the range is near the floating point limit, + #let seq generate some equally spaced steps. + return(seq(from = dmin, to = dmax, length.out = n)) + } + n <- length(Q) + best <- list() + best$score <- -2 + j <- 1 + while (j < Inf) { + for (q in Q) { + sm <- simplicity_max(q, Q, j) + if ((w[1] * sm + w[2] + w[3] + w[4]) < best$score) { + j <- Inf break - - delta <- (dmax - dmin) / (k + 1) / j / q - z <- ceiling(log(delta, base = 10)) - - while (z < Inf) { - step <- j * q * 10 ^ z - - cm <- coverage_max(dmin, dmax, step * (k - 1)) - - if ( (w[1] * sm + w[2] * cm + w[3] * dm + w[4]) < best$score) + } + k <- 2 + while (k < Inf) { + dm <- density_max(k, n) + if ((w[1] * sm + w[2] + w[3] * dm + w[4]) < best$score) { break - - min_start <- floor(dmax / (step)) * j - (k - 1) * j - max_start <- ceiling(dmin / (step)) * j - - if (min_start > max_start) { - z <- z + 1 - next } - - for (start in min_start:max_start) { - lmin <- start * (step / j) - lmax <- lmin + step * (k - 1) - lstep <- step - - s <- simplicity(q, Q, j, lmin, lmax, lstep) - c <- coverage(dmin, dmax, lmin, lmax) - g <- dens(k, n, dmin, dmax, lmin, lmax) - l <- legibility(lmin, lmax, lstep) - - score <- w[1] * s + w[2] * c + w[3] * g + w[4] * l - - if (score > best$score - && lmin >= dmin - && lmax <= dmax) { + delta <- (dmax - dmin) / (k + 1) / j / q + z <- ceiling(log(delta, base = 10)) + while (z < Inf) { + step <- j * q * 10 ^ z + cm <- coverage_max(dmin, dmax, step * (k - 1)) + if ((w[1] * sm + w[2] * cm + w[3] * dm + w[4]) < best$score) { + break + } + min_start <- floor(dmax / (step)) * j - (k - 1) * j + max_start <- ceiling(dmin / (step)) * j + if (min_start > max_start) { + z <- z + 1 + next + } + for (start in min_start:max_start) { + lmin <- start * (step / j) + lmax <- lmin + step * (k - 1) + lstep <- step + s <- simplicity(q, Q, j, lmin, lmax, lstep) + c <- coverage(dmin, dmax, lmin, lmax) + g <- dens(k, n, dmin, dmax, lmin, lmax) + l <- legibility(lmin, lmax, lstep) + score <- w[1] * s + w[2] * c + w[3] * g + w[4] * l + if (score > best$score + && lmin >= dmin + && lmax <= dmax) { best <- list(lmin = lmin, lmax = lmax, lstep = lstep, score = score) + } } + z <- z + 1 } - z <- z + 1 + k <- k + 1 } - k <- k + 1 } + j <- j + 1 } - j <- j + 1 - } - breaks <- seq(from = best$lmin, to = best$lmax, by = best$lstep) - if (length(breaks) >= 2) { + breaks <- seq(from = best$lmin, to = best$lmax, by = best$lstep) + if (length(breaks) >= 2) { breaks[1] <- dmin breaks[length(breaks)] <- dmax - } - breaks -} - -#' @rdname range_breaks -#' @param ... other arguments passed to \code{extended_range_breaks_} -#' @return A function which returns breaks given a vector. -#' @export -extended_range_breaks <- function(n = 5, ...) { - function(x) { - extended_range_breaks_(min(x), max(x), n, ...) } + breaks + } } # from scales package @@ -191,7 +159,7 @@ zero_range <- function(x, tol = 1000 * .Machine$double.eps) { m <- min(abs(x)) if (m == 0) return(FALSE) - abs( (x[1] - x[2]) / m) < tol + abs((x[1] - x[2]) / m) < tol } # from scales package @@ -200,7 +168,7 @@ precision <- function(x) { span <- if (zero_range(rng)) abs(rng[1]) else diff(rng) - 10 ^ floor(log10(span)) + floor(log10(span)) } #' Format numbers with automatic number of digits @@ -214,17 +182,16 @@ precision <- function(x) { #' \code{smart_digits_format} returns a function with a single argument \code{x}, a numeric vector, that returns a character vector. #' #' @rdname smart_digits -#' @export +#' @noRd smart_digits <- function(x, ...) { if (length(x) == 0) return(character()) accuracy <- precision(x) - x <- round(x / accuracy) * accuracy + x <- round(x, -accuracy) format(x, ...) } -#' @rdname smart_digits -#' @export +#' @noRd smart_digits_format <- function(x, ...) { - function(x) smart_digits(x, ...) + function(x) smart_digits(x, ...) } diff --git a/R/tufte.R b/R/tufte.R index 30eb7ed..c129366 100644 --- a/R/tufte.R +++ b/R/tufte.R @@ -1,61 +1,52 @@ -#' Tufte Maximal Data, Minimal Ink Theme +#' Tufte's Maximal Data, Minimal Ink Theme #' #' Theme based on Chapter 6 'Data-Ink Maximization and Graphical -#' Design' of Edward Tufte *The Visual Display of Quantitative -#' Information*. No border, no axis lines, no grids. This theme works -#' best in combination with \code{\link{geom_rug}} or +#' Design' of Tufte *The Visual Display of Quantitative Information*. +#' No border, no axis lines, no grids. This theme works +#' well in combination with \code{\link{geom_rug}} or #' \code{\link{geom_rangeframe}}. #' -#' @note -#' The default font family is set to 'serif' as he uses serif fonts -#' for labels in 'The Visual Display of Quantitative Information'. -#' The serif font used by Tufte in his books is a variant of Bembo, -#' while the sans serif font is Gill Sans. If these fonts are -#' installed on your system, then you can use them with the package -#' \bold{extrafont}. -#' #' @inheritParams ggplot2::theme_grey #' @param ticks \code{logical} Show axis ticks? #' #' @references Tufte, Edward R. (2001) The Visual Display of #' Quantitative Information, Chapter 6. #' +#' @md #' @family themes tufte #' @example examples/ex-theme_tufte.R #' @export -#' @importFrom ggplot2 theme element_blank theme_bw -theme_tufte <- function(base_size = 11, - base_family = extrafont::choose_font(ggtufte::tufte_theme_fonts), - ticks = TRUE) { - ret <- theme_bw(base_family = base_family, base_size = base_size) + - theme(legend.background = element_blank(), - legend.key = element_blank(), - panel.background = element_blank(), - panel.border = element_blank(), - strip.background = element_blank(), - plot.background = element_blank(), - axis.line = element_blank(), - panel.grid = element_blank()) +#' @importFrom ggplot2 theme element_blank element_text theme_bw +theme_tufte <- function(base_size = 11, ticks = TRUE, sans_title = FALSE) { + font_roman <- get_etbembo() + font_italic <- get_etbembo(italic = TRUE) + font_sans <- get_gill_sans() + + title_font <- if (sans_title) { + get_gill_sans() + } else { + font_italic + } + + ret <- theme_bw(base_family = font_roman, base_size = base_size) + + theme( + text = element_text(family = font_roman), + plot.title = element_text(family = title_font, + face = if (sans_title) "plain" else "italic"), + plot.subtitle = element_text(family = title_font, + face = if (sans_title) "plain" else "italic"), + plot.caption = element_text(hjust = 0), + legend.background = element_blank(), + legend.key = element_blank(), + panel.background = element_blank(), + panel.border = element_blank(), + strip.background = element_blank(), + plot.background = element_blank(), + axis.line = element_blank(), + panel.grid = element_blank() + ) if (!ticks) { ret <- ret + theme(axis.ticks = element_blank()) } ret } - -#' Font options to use with the Tufte Theme -#' -#' List of font or font-families to use with \code{theme_tufte}. -#' It starts with the preferred ETBembo font used in Tufte's book along with -#' fallback options. -#' -#' This list is derived from the list of fonts used in -#' [https://github.com/edwardtufte/tufte-css](tufte-css) -#' -#' @md -#' @format A character vector. -#' @export -#' @examples -#' tufte_theme_fonts -tufte_theme_fonts <- -c("ETBembo RomanLF", "Palatino", "Palatino Linotype", "Palatino LT STD", - "Book Antiqua", "Georgia", "serif") \ No newline at end of file diff --git a/_pkgdown.yml b/_pkgdown.yml new file mode 100644 index 0000000..e69de29 diff --git a/docs/CONDUCT.html b/docs/CONDUCT.html new file mode 100644 index 0000000..4097c95 --- /dev/null +++ b/docs/CONDUCT.html @@ -0,0 +1,143 @@ + + + + + + + + +Contributor Code of Conduct • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+ +

As contributors and maintainers of this project, we pledge to respect all people who contribute through reporting issues, posting feature requests, updating documentation, submitting pull requests or patches, and other activities.

+

We are committed to making participation in this project a harassment-free experience for everyone, regardless of level of experience, gender, gender identity and expression, sexual orientation, disability, personal appearance, body size, race, ethnicity, age, or religion.

+

Examples of unacceptable behavior by participants include the use of sexual language or imagery, derogatory comments or personal attacks, trolling, public or private harassment, insults, or other unprofessional conduct.

+

Project maintainers have the right and responsibility to remove, edit, or reject comments, commits, code, wiki edits, issues, and other contributions that are not aligned to this Code of Conduct. Project maintainers who do not follow the Code of Conduct may be removed from the project team.

+

Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by opening an issue or contacting one or more of the project maintainers.

+

This Code of Conduct is adapted from the Contributor Covenant (http:contributor-covenant.org), version 1.0.0, available at http://contributor-covenant.org/version/1/0/0/

+
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + + + + diff --git a/docs/LICENSE-text.html b/docs/LICENSE-text.html new file mode 100644 index 0000000..227b4c1 --- /dev/null +++ b/docs/LICENSE-text.html @@ -0,0 +1,137 @@ + + + + + + + + +License • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
YEAR: 2018
+COPYRIGHT HOLDER: Jeffrey Arnold
+
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + + + + diff --git a/docs/LICENSE.html b/docs/LICENSE.html new file mode 100644 index 0000000..6282bc5 --- /dev/null +++ b/docs/LICENSE.html @@ -0,0 +1,141 @@ + + + + + + + + +MIT License • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+ +

Copyright (c) 2018 Jeffrey Arnold

+

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the “Software”), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

+

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

+

THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

+
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + + + + diff --git a/docs/articles/index.html b/docs/articles/index.html new file mode 100644 index 0000000..638be33 --- /dev/null +++ b/docs/articles/index.html @@ -0,0 +1,139 @@ + + + + + + + + +Articles • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+

All vignettes

+

+ + +
+
+
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + + + + diff --git a/docs/articles/intro.html b/docs/articles/intro.html new file mode 100644 index 0000000..195be0a --- /dev/null +++ b/docs/articles/intro.html @@ -0,0 +1,160 @@ + + + + + + + +The <code>ggtufte</code> Package • ggtufte + + + + + + + + + +
+
+ + + +
+
+ + + + +
+

+Introduction

+
library("ggplot2")
+library("ggtufte")
+extrafont::loadfonts()
+
## Registering font with R using pdfFonts(): ETBembo
+
+

+Minimal Bar Plot

+
+
+

+Minimal Scatterplot with Range-Frame

+
+
+

+Typography

+
+
+

+References

+ +
+
+
+ + + +
+ + +
+ +
+

Site built with pkgdown.

+
+ +
+
+ + + + + diff --git a/docs/authors.html b/docs/authors.html new file mode 100644 index 0000000..48af2fa --- /dev/null +++ b/docs/authors.html @@ -0,0 +1,164 @@ + + + + + + + + +Authors • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
    +
  • +

    Jeffrey Arnold. Author, maintainer. +

    +
  • +
  • +

    Hadley Wickham. Contributor. +
    Code from the ggplot2 package.

    +
  • +
  • +

    Justin Talbot. Contributor. +
    Code from the labeling package

    +
  • +
  • +

    Dimitry Krasny. Copyright holder. +
    ET Book Font

    +
  • +
  • +

    Bonnie Scranton. Copyright holder. +
    ET Book Font

    +
  • +
  • +

    Edward Tufte. Copyright holder. +
    ET Book Font

    +
  • +
  • +

    Bob Rudis. Contributor. +
    Code from hrbrthemes package.

    +
  • +
+ +
+ +
+ + +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + + + + diff --git a/docs/docsearch.css b/docs/docsearch.css new file mode 100644 index 0000000..c524034 --- /dev/null +++ b/docs/docsearch.css @@ -0,0 +1,145 @@ +/* Docsearch -------------------------------------------------------------- */ +/* + Source: https://github.com/algolia/docsearch/ + License: MIT +*/ + +.algolia-autocomplete { + display: block; + -webkit-box-flex: 1; + -ms-flex: 1; + flex: 1 +} + +.algolia-autocomplete .ds-dropdown-menu { + width: 100%; + min-width: none; + max-width: none; + padding: .75rem 0; + background-color: #fff; + background-clip: padding-box; + border: 1px solid rgba(0, 0, 0, .1); + box-shadow: 0 .5rem 1rem rgba(0, 0, 0, .175); +} + +@media (min-width:768px) { + .algolia-autocomplete .ds-dropdown-menu { + width: 175% + } +} + +.algolia-autocomplete .ds-dropdown-menu::before { + display: none +} + +.algolia-autocomplete .ds-dropdown-menu [class^=ds-dataset-] { + padding: 0; + background-color: rgb(255,255,255); + border: 0; + max-height: 80vh; +} + +.algolia-autocomplete .ds-dropdown-menu .ds-suggestions { + margin-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion { + padding: 0; + overflow: visible +} + +.algolia-autocomplete .algolia-docsearch-suggestion--category-header { + padding: .125rem 1rem; + margin-top: 0; + font-size: 1.3em; + font-weight: 500; + color: #00008B; + border-bottom: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--wrapper { + float: none; + padding-top: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--subcategory-column { + float: none; + width: auto; + padding: 0; + text-align: left +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content { + float: none; + width: auto; + padding: 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--content::before { + display: none +} + +.algolia-autocomplete .ds-suggestion:not(:first-child) .algolia-docsearch-suggestion--category-header { + padding-top: .75rem; + margin-top: .75rem; + border-top: 1px solid rgba(0, 0, 0, .1) +} + +.algolia-autocomplete .ds-suggestion .algolia-docsearch-suggestion--subcategory-column { + display: block; + padding: .1rem 1rem; + margin-bottom: 0.1; + font-size: 1.0em; + font-weight: 400 + /* display: none */ +} + +.algolia-autocomplete .algolia-docsearch-suggestion--title { + display: block; + padding: .25rem 1rem; + margin-bottom: 0; + font-size: 0.9em; + font-weight: 400 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--text { + padding: 0 1rem .5rem; + margin-top: -.25rem; + font-size: 0.8em; + font-weight: 400; + line-height: 1.25 +} + +.algolia-autocomplete .algolia-docsearch-footer { + float: none; + width: auto; + height: auto; + padding: .75rem 1rem 0; + font-size: .95rem; + line-height: 1; + color: #767676; + background-color: rgb(255, 255, 255); + border-top: 1px solid rgba(0, 0, 0, .1) +} + +.algolia-autocomplete .algolia-docsearch-footer--logo { + display: inline; + overflow: visible; + color: inherit; + text-indent: 0; + background: 0 0 +} + +.algolia-autocomplete .algolia-docsearch-suggestion--highlight { + color: #FF8C00; + background: rgba(232, 189, 54, 0.1) +} + + +.algolia-autocomplete .algolia-docsearch-suggestion--text .algolia-docsearch-suggestion--highlight { + box-shadow: inset 0 -2px 0 0 rgba(105, 105, 105, .5) +} + +.algolia-autocomplete .ds-suggestion.ds-cursor .algolia-docsearch-suggestion--content { + background-color: rgba(192, 192, 192, .15) +} diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 0000000..76eef61 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,145 @@ + + + + + + + +Themes and geoms implementing Tufte's work in 'ggplot2' • ggtufte + + + + + + + + + +
+
+ + + +
+
+
+

+ggtufte: Geoms and theme implementing Tufte’s style in ggplot2

+ +
+

The ggtufte package provides ggplot2 theme and geoms inspired by the work of Edward Tufte.

+

These functions were formerly contained in the ggthemes package and have been split into their own package.

+
+
+ + +
+ + +
+ +
+

Site built with pkgdown.

+
+ +
+
+ + + + + diff --git a/docs/jquery.sticky-kit.min.js b/docs/jquery.sticky-kit.min.js new file mode 100644 index 0000000..1c16271 --- /dev/null +++ b/docs/jquery.sticky-kit.min.js @@ -0,0 +1,11 @@ +/* Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | */ +/* + Source: https://github.com/leafo/sticky-kit + License: MIT +*/ +(function(){var b,f;b=this.jQuery||window.jQuery;f=b(window);b.fn.stick_in_parent=function(d){var A,w,J,n,B,K,p,q,k,E,t;null==d&&(d={});t=d.sticky_class;B=d.inner_scrolling;E=d.recalc_every;k=d.parent;q=d.offset_top;p=d.spacer;w=d.bottoming;null==q&&(q=0);null==k&&(k=void 0);null==B&&(B=!0);null==t&&(t="is_stuck");A=b(document);null==w&&(w=!0);J=function(a,d,n,C,F,u,r,G){var v,H,m,D,I,c,g,x,y,z,h,l;if(!a.data("sticky_kit")){a.data("sticky_kit",!0);I=A.height();g=a.parent();null!=k&&(g=g.closest(k)); +if(!g.length)throw"failed to find stick parent";v=m=!1;(h=null!=p?p&&a.closest(p):b("
"))&&h.css("position",a.css("position"));x=function(){var c,f,e;if(!G&&(I=A.height(),c=parseInt(g.css("border-top-width"),10),f=parseInt(g.css("padding-top"),10),d=parseInt(g.css("padding-bottom"),10),n=g.offset().top+c+f,C=g.height(),m&&(v=m=!1,null==p&&(a.insertAfter(h),h.detach()),a.css({position:"",top:"",width:"",bottom:""}).removeClass(t),e=!0),F=a.offset().top-(parseInt(a.css("margin-top"),10)||0)-q, +u=a.outerHeight(!0),r=a.css("float"),h&&h.css({width:a.outerWidth(!0),height:u,display:a.css("display"),"vertical-align":a.css("vertical-align"),"float":r}),e))return l()};x();if(u!==C)return D=void 0,c=q,z=E,l=function(){var b,l,e,k;if(!G&&(e=!1,null!=z&&(--z,0>=z&&(z=E,x(),e=!0)),e||A.height()===I||x(),e=f.scrollTop(),null!=D&&(l=e-D),D=e,m?(w&&(k=e+u+c>C+n,v&&!k&&(v=!1,a.css({position:"fixed",bottom:"",top:c}).trigger("sticky_kit:unbottom"))),eb&&!v&&(c-=l,c=Math.max(b-u,c),c=Math.min(q,c),m&&a.css({top:c+"px"})))):e>F&&(m=!0,b={position:"fixed",top:c},b.width="border-box"===a.css("box-sizing")?a.outerWidth()+"px":a.width()+"px",a.css(b).addClass(t),null==p&&(a.after(h),"left"!==r&&"right"!==r||h.append(a)),a.trigger("sticky_kit:stick")),m&&w&&(null==k&&(k=e+u+c>C+n),!v&&k)))return v=!0,"static"===g.css("position")&&g.css({position:"relative"}), +a.css({position:"absolute",bottom:d,top:"auto"}).trigger("sticky_kit:bottom")},y=function(){x();return l()},H=function(){G=!0;f.off("touchmove",l);f.off("scroll",l);f.off("resize",y);b(document.body).off("sticky_kit:recalc",y);a.off("sticky_kit:detach",H);a.removeData("sticky_kit");a.css({position:"",bottom:"",top:"",width:""});g.position("position","");if(m)return null==p&&("left"!==r&&"right"!==r||a.insertAfter(h),h.remove()),a.removeClass(t)},f.on("touchmove",l),f.on("scroll",l),f.on("resize", +y),b(document.body).on("sticky_kit:recalc",y),a.on("sticky_kit:detach",H),setTimeout(l,0)}};n=0;for(K=this.length;n + + + + + diff --git a/docs/news/index.html b/docs/news/index.html new file mode 100644 index 0000000..4f8e3ad --- /dev/null +++ b/docs/news/index.html @@ -0,0 +1,150 @@ + + + + + + + + +Changelog • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
+
+ + + +
+ +
+
+ + +
+

+ggtufte 0.0.1

+
    +
  • Initial release
  • +
  • Copied theme_tufte, extended_range_breaks, geom_rangeframe, geom_tufteboxplot, stat_fivenumber from the ggthemes package (ef9e0fc6214122d8fa66c4d80ba163a2ba504801).
  • +
+
+
+ + + +
+ +
+ + +
+

Site built with pkgdown.

+
+ +
+
+ + + + + + diff --git a/docs/pkgdown.css b/docs/pkgdown.css new file mode 100644 index 0000000..c5ab586 --- /dev/null +++ b/docs/pkgdown.css @@ -0,0 +1,227 @@ +/* Sticky footer */ + +/** + * Basic idea: https://philipwalton.github.io/solved-by-flexbox/demos/sticky-footer/ + * Details: https://github.com/philipwalton/solved-by-flexbox/blob/master/assets/css/components/site.css + * + * .Site -> body > .container + * .Site-content -> body > .container .row + * .footer -> footer + * + * Key idea seems to be to ensure that .container and __all its parents__ + * have height set to 100% + * + */ + +html, body { + height: 100%; +} + +body > .container { + display: flex; + height: 100%; + flex-direction: column; + + padding-top: 60px; +} + +body > .container .row { + flex: 1 0 auto; +} + +footer { + margin-top: 45px; + padding: 35px 0 36px; + border-top: 1px solid #e5e5e5; + color: #666; + display: flex; + flex-shrink: 0; +} +footer p { + margin-bottom: 0; +} +footer div { + flex: 1; +} +footer .pkgdown { + text-align: right; +} +footer p { + margin-bottom: 0; +} + +img.icon { + float: right; +} + +img { + max-width: 100%; +} + +/* Typographic tweaking ---------------------------------*/ + +.contents h1.page-header { + margin-top: calc(-60px + 1em); +} + +/* Section anchors ---------------------------------*/ + +a.anchor { + margin-left: -30px; + display:inline-block; + width: 30px; + height: 30px; + visibility: hidden; + + background-image: url(./link.svg); + background-repeat: no-repeat; + background-size: 20px 20px; + background-position: center center; +} + +.hasAnchor:hover a.anchor { + visibility: visible; +} + +@media (max-width: 767px) { + .hasAnchor:hover a.anchor { + visibility: hidden; + } +} + + +/* Fixes for fixed navbar --------------------------*/ + +.contents h1, .contents h2, .contents h3, .contents h4 { + padding-top: 60px; + margin-top: -40px; +} + +/* Static header placement on mobile devices */ +@media (max-width: 767px) { + .navbar-fixed-top { + position: absolute; + } + .navbar { + padding: 0; + } +} + + +/* Sidebar --------------------------*/ + +#sidebar { + margin-top: 30px; +} +#sidebar h2 { + font-size: 1.5em; + margin-top: 1em; +} + +#sidebar h2:first-child { + margin-top: 0; +} + +#sidebar .list-unstyled li { + margin-bottom: 0.5em; +} + +.orcid { + height: 16px; + vertical-align: middle; +} + +/* Reference index & topics ----------------------------------------------- */ + +.ref-index th {font-weight: normal;} + +.ref-index td {vertical-align: top;} +.ref-index .alias {width: 40%;} +.ref-index .title {width: 60%;} + +.ref-index .alias {width: 40%;} +.ref-index .title {width: 60%;} + +.ref-arguments th {text-align: right; padding-right: 10px;} +.ref-arguments th, .ref-arguments td {vertical-align: top;} +.ref-arguments .name {width: 20%;} +.ref-arguments .desc {width: 80%;} + +/* Nice scrolling for wide elements --------------------------------------- */ + +table { + display: block; + overflow: auto; +} + +/* Syntax highlighting ---------------------------------------------------- */ + +pre { + word-wrap: normal; + word-break: normal; + border: 1px solid #eee; +} + +pre, code { + background-color: #f8f8f8; + color: #333; +} + +pre code { + overflow: auto; + word-wrap: normal; + white-space: pre; +} + +pre .img { + margin: 5px 0; +} + +pre .img img { + background-color: #fff; + display: block; + height: auto; +} + +code a, pre a { + color: #375f84; +} + +a.sourceLine:hover { + text-decoration: none; +} + +.fl {color: #1514b5;} +.fu {color: #000000;} /* function */ +.ch,.st {color: #036a07;} /* string */ +.kw {color: #264D66;} /* keyword */ +.co {color: #888888;} /* comment */ + +.message { color: black; font-weight: bolder;} +.error { color: orange; font-weight: bolder;} +.warning { color: #6A0366; font-weight: bolder;} + +/* Clipboard --------------------------*/ + +.hasCopyButton { + position: relative; +} + +.btn-copy-ex { + position: absolute; + right: 0; + top: 0; + visibility: hidden; +} + +.hasCopyButton:hover button.btn-copy-ex { + visibility: visible; +} + +/* mark.js ----------------------------*/ + +mark { + background-color: rgba(255, 255, 51, 0.5); + border-bottom: 2px solid rgba(255, 153, 51, 0.3); + padding: 1px; +} diff --git a/docs/pkgdown.js b/docs/pkgdown.js new file mode 100644 index 0000000..16d5750 --- /dev/null +++ b/docs/pkgdown.js @@ -0,0 +1,174 @@ +$(function() { + + $("#sidebar") + .stick_in_parent({offset_top: 40}) + .on('sticky_kit:bottom', function(e) { + $(this).parent().css('position', 'static'); + }) + .on('sticky_kit:unbottom', function(e) { + $(this).parent().css('position', 'relative'); + }); + + $('body').scrollspy({ + target: '#sidebar', + offset: 60 + }); + + $('[data-toggle="tooltip"]').tooltip(); + + var cur_path = paths(location.pathname); + $("#navbar ul li a").each(function(index, value) { + if (value.text == "Home") + return; + if (value.getAttribute("href") === "#") + return; + + var path = paths(value.pathname); + if (is_prefix(cur_path, path)) { + // Add class to parent
  • , and enclosing
  • if in dropdown + var menu_anchor = $(value); + menu_anchor.parent().addClass("active"); + menu_anchor.closest("li.dropdown").addClass("active"); + } + }); +}); + +$(document).ready(function() { + // do keyword highlighting + /* modified from https://jsfiddle.net/julmot/bL6bb5oo/ */ + var mark = function() { + + var referrer = document.URL ; + var paramKey = "q" ; + + if (referrer.indexOf("?") !== -1) { + var qs = referrer.substr(referrer.indexOf('?') + 1); + var qs_noanchor = qs.split('#')[0]; + var qsa = qs_noanchor.split('&'); + var keyword = ""; + + for (var i = 0; i < qsa.length; i++) { + var currentParam = qsa[i].split('='); + + if (currentParam.length !== 2) { + continue; + } + + if (currentParam[0] == paramKey) { + keyword = decodeURIComponent(currentParam[1].replace(/\+/g, "%20")); + } + } + + if (keyword !== "") { + $(".contents").unmark({ + done: function() { + $(".contents").mark(keyword); + } + }); + } + } + }; + + mark(); +}); + +function paths(pathname) { + var pieces = pathname.split("/"); + pieces.shift(); // always starts with / + + var end = pieces[pieces.length - 1]; + if (end === "index.html" || end === "") + pieces.pop(); + return(pieces); +} + +function is_prefix(needle, haystack) { + if (needle.length > haystack.lengh) + return(false); + + // Special case for length-0 haystack, since for loop won't run + if (haystack.length === 0) { + return(needle.length === 0); + } + + for (var i = 0; i < haystack.length; i++) { + if (needle[i] != haystack[i]) + return(false); + } + + return(true); +} + +/* Clipboard --------------------------*/ + +function changeTooltipMessage(element, msg) { + var tooltipOriginalTitle=element.getAttribute('data-original-title'); + element.setAttribute('data-original-title', msg); + $(element).tooltip('show'); + element.setAttribute('data-original-title', tooltipOriginalTitle); +} + +if(Clipboard.isSupported()) { + $(document).ready(function() { + var copyButton = ""; + + $(".examples").addClass("hasCopyButton"); + + // Insert copy buttons: + $(copyButton).prependTo(".hasCopyButton"); + + // Initialize tooltips: + $('.btn-copy-ex').tooltip({container: 'body'}); + + // Initialize clipboard: + var clipboardBtnCopies = new Clipboard('[data-clipboard-copy]', { + text: function(trigger) { + return trigger.parentNode.textContent; + } + }); + + clipboardBtnCopies.on('success', function(e) { + changeTooltipMessage(e.trigger, 'Copied!'); + e.clearSelection(); + }); + + clipboardBtnCopies.on('error', function() { + changeTooltipMessage(e.trigger,'Press Ctrl+C or Command+C to copy'); + }); + }); +} + +/* Search term highlighting ------------------------------*/ + +function matchedWords(hit) { + var words = []; + + var hierarchy = hit._highlightResult.hierarchy; + // loop to fetch from lvl0, lvl1, etc. + for (var idx in hierarchy) { + words = words.concat(hierarchy[idx].matchedWords); + } + + var content = hit._highlightResult.content; + if (content) { + words = words.concat(content.matchedWords); + } + + // return unique words + var words_uniq = [...new Set(words)]; + return words_uniq; +} + +function updateHitURL(hit) { + + var words = matchedWords(hit); + var url = ""; + + if (hit.anchor) { + url = hit.url_without_anchor + '?q=' + escape(words.join(" ")) + '#' + hit.anchor; + } else { + url = hit.url + '?q=' + escape(words.join(" ")); + } + + return url; +} diff --git a/docs/pkgdown.yml b/docs/pkgdown.yml new file mode 100644 index 0000000..5eec146 --- /dev/null +++ b/docs/pkgdown.yml @@ -0,0 +1,6 @@ +pandoc: 1.19.2.1 +pkgdown: 1.0.0 +pkgdown_sha: ~ +articles: + intro: intro.html + diff --git a/docs/reference/ETBembo.html b/docs/reference/ETBembo.html new file mode 100644 index 0000000..af43440 --- /dev/null +++ b/docs/reference/ETBembo.html @@ -0,0 +1,179 @@ + + + + + + + + +ET Book fonts R variable aliases — font_et • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    ET Book fonts

    + +
    + +
    font_et
    + +

    Format

    + +

    length 5 character vector. Values are the +font names, and names are the description of the font.

    + +

    Details

    + +

    ET Book (ETBembo font-family) comprises five fonts:

      +
    • "ETBembo RomanLF": Roman (lining figures)

    • +
    • "ETBembo RomanOSF": Roman (oldstyle figures)

    • +
    • "ETBembo SemiBoldOSF": Semi-bold (oldstyle figures)

    • +
    • "ETBembo BoldLF": Bold (lining figures)

    • +
    • "ETBembo DisplayItalic": Display Italic (oldstyle figures)

    • +
    + + +

    Examples

    +
    font_et
    #> Roman (line figures) Roman (old-style figures) +#> "ETBembo RomanLF" "ETBembo RomanOSF" +#> Bold (line figures) Semi-bold (old-style figures) +#> "ETBembo BoldLF" "ETBembo SemiBoldOSF" +#> Display italic +#> "ETBembo DisplayItalic"
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/geom_rangeframe-1.png b/docs/reference/geom_rangeframe-1.png new file mode 100644 index 0000000..102e45e Binary files /dev/null and b/docs/reference/geom_rangeframe-1.png differ diff --git a/docs/reference/geom_rangeframe.html b/docs/reference/geom_rangeframe.html new file mode 100644 index 0000000..f8e23a0 --- /dev/null +++ b/docs/reference/geom_rangeframe.html @@ -0,0 +1,256 @@ + + + + + + + + +Range Frames — geom_rangeframe • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Axis lines which extend to the maximum and minimum of the plotted data.

    + +
    + +
    geom_rangeframe(mapping = NULL, data = NULL, stat = "identity",
    +  position = "identity", ..., sides = "bl", na.rm = FALSE,
    +  show.legend = NA, inherit.aes = TRUE)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    mapping

    Set of aesthetic mappings created by aes() or +aes_(). If specified and inherit.aes = TRUE (the +default), it is combined with the default mapping at the top level of the +plot. You must supply mapping if there is no plot mapping.

    data

    The data to be displayed in this layer. There are three +options:

    +

    If NULL, the default, the data is inherited from the plot +data as specified in the call to ggplot().

    +

    A data.frame, or other object, will override the plot +data. All objects will be fortified to produce a data frame. See +fortify() for which variables will be created.

    +

    A function will be called with a single argument, +the plot data. The return value must be a data.frame., and +will be used as the layer data.

    stat

    The statistical transformation to use on the data for this +layer, as a string.

    position

    Position adjustment, either as a string, or the result of +a call to a position adjustment function.

    ...

    Other arguments passed on to layer(). These are +often aesthetics, used to set an aesthetic to a fixed value, like +color = "red" or size = 3. They may also be parameters +to the paired geom/stat.

    sides

    A string that controls which sides of the plot the frames appear on. +It can be set to a string containing any of 'trbl', for top, right, +bottom, and left.

    na.rm

    If FALSE, the default, missing values are removed with +a warning. If TRUE, missing values are silently removed.

    show.legend

    logical. Should this layer be included in the legends? +NA, the default, includes if any aesthetics are mapped. +FALSE never includes, and TRUE always includes. +It can also be a named logical vector to finely select the aesthetics to +display.

    inherit.aes

    If FALSE, overrides the default aesthetics, +rather than combining with them. This is most useful for helper functions +that define both data and aesthetics and shouldn't inherit behaviour from +the default plot specification, e.g. borders().

    + +

    Aesthetics

    + + +
      +
    • colour

    • +
    • size

    • +
    • linetype

    • +
    • alpha

    • +
    + +

    References

    + +

    Tufte, Edward R. (2001) The Visual Display of +Quantitative Information, Chapter 6.

    + +

    See also

    + +

    Other geom tufte: geom_tufteboxplot

    + + +

    Examples

    +
    library("ggplot2") +library("extrafont")
    #> Registering fonts with R
    extrafont::loadfonts()
    #> ETBembo already registered with pdfFonts().
    +ggplot(mtcars, aes(wt, mpg)) + + geom_point() + + geom_rangeframe() + + theme_tufte()
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/geom_tufteboxplot-1.png b/docs/reference/geom_tufteboxplot-1.png new file mode 100644 index 0000000..ed4aba8 Binary files /dev/null and b/docs/reference/geom_tufteboxplot-1.png differ diff --git a/docs/reference/geom_tufteboxplot-2.png b/docs/reference/geom_tufteboxplot-2.png new file mode 100644 index 0000000..cdf5fe1 Binary files /dev/null and b/docs/reference/geom_tufteboxplot-2.png differ diff --git a/docs/reference/geom_tufteboxplot-3.png b/docs/reference/geom_tufteboxplot-3.png new file mode 100644 index 0000000..46af947 Binary files /dev/null and b/docs/reference/geom_tufteboxplot-3.png differ diff --git a/docs/reference/geom_tufteboxplot-4.png b/docs/reference/geom_tufteboxplot-4.png new file mode 100644 index 0000000..45c88ab Binary files /dev/null and b/docs/reference/geom_tufteboxplot-4.png differ diff --git a/docs/reference/geom_tufteboxplot-5.png b/docs/reference/geom_tufteboxplot-5.png new file mode 100644 index 0000000..5c8b309 Binary files /dev/null and b/docs/reference/geom_tufteboxplot-5.png differ diff --git a/docs/reference/geom_tufteboxplot.html b/docs/reference/geom_tufteboxplot.html new file mode 100644 index 0000000..0dd1a1c --- /dev/null +++ b/docs/reference/geom_tufteboxplot.html @@ -0,0 +1,332 @@ + + + + + + + + +Tufte's Box Plot — geom_tufteboxplot • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Edward Tufte's revisions of the box plot as described in +The Visual Display of Quantitative Information. +This functions provides several box plot variants:

      +
    • A point indicating the median, a gap indicating the + interquartile range, and lines for whiskers.

    • +
    • An offset line indicating the interquartile range + and a gap indicating the median.

    • +
    • A line indicating the interquartile range, + a gap indicating the median, and points indicating + the minimum and maximum values

    • +
    • A wide line indicating the interquartile range, + a gap indicating the median, and lines indicating the minimum and + maximum.

    • +
    + +
    + +
    geom_tufteboxplot(mapping = NULL, data = NULL, stat = "fivenumber",
    +  position = "dodge", outlier.colour = "black", outlier.shape = 19,
    +  outlier.size = 1.5, outlier.stroke = 0.5, voffset = 0.01,
    +  hoffset = 0.005, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE,
    +  median.type = "point", whisker.type = "line", ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    mapping

    Set of aesthetic mappings created by aes() or +aes_(). If specified and inherit.aes = TRUE (the +default), it is combined with the default mapping at the top level of the +plot. You must supply mapping if there is no plot mapping.

    data

    The data to be displayed in this layer. There are three +options:

    +

    If NULL, the default, the data is inherited from the plot +data as specified in the call to ggplot().

    +

    A data.frame, or other object, will override the plot +data. All objects will be fortified to produce a data frame. See +fortify() for which variables will be created.

    +

    A function will be called with a single argument, +the plot data. The return value must be a data.frame., and +will be used as the layer data.

    stat

    The statistical transformation to use on the data for this +layer, as a string.

    position

    Position adjustment, either as a string, or the result of +a call to a position adjustment function.

    outlier.colour

    colour for outlying points

    outlier.shape

    shape of outlying points

    outlier.size

    size of outlying points

    outlier.stroke

    stroke for outlying points

    voffset

    controls the size of the gap in the line representing the +median when median.type = 'line'. This is a fraction of the range +of y.

    hoffset

    controls how much the interquartile line is offset from the +whiskers when median.type = 'line'. This is a fraction of the +range of x.

    na.rm

    If FALSE, the default, missing values are removed with +a warning. If TRUE, missing values are silently removed.

    show.legend

    logical. Should this layer be included in the legends? +NA, the default, includes if any aesthetics are mapped. +FALSE never includes, and TRUE always includes. +It can also be a named logical vector to finely select the aesthetics to +display.

    inherit.aes

    If FALSE, overrides the default aesthetics, +rather than combining with them. This is most useful for helper functions +that define both data and aesthetics and shouldn't inherit behaviour from +the default plot specification, e.g. borders().

    median.type

    If 'point', then the median is represented by a +point, and the interquartile range by a gap in the line. If +median.type='line', then the interquartile range is represented by +a line, possibly offset, and the median by a gap in the line.

    whisker.type

    If 'line', then whiskers are represented by lines. +If 'point', then whiskers are represented by points at +ymin and ymax.

    ...

    Other arguments passed on to layer(). These are +often aesthetics, used to set an aesthetic to a fixed value, like +color = "red" or size = 3. They may also be parameters +to the paired geom/stat.

    + +

    Aesthetics

    + + +
      +
    • x [required]

    • +
    • y [required]

    • +
    • colour

    • +
    • size

    • +
    • linetype

    • +
    • shape

    • +
    • fill

    • +
    • alpha

    • +
    + +

    References

    + +

    Tufte, Edward R. (2001) The Visual Display of +Quantitative Information, Chapter 6.

    +

    McGill, R., Tukey, J. W. and Larsen, W. A. (1978) Variations of +box plots. The American Statistician 32, 12-16.

    + +

    See also

    + +

    geom_boxplot

    +

    Other geom tufte: geom_rangeframe

    + + +

    Examples

    +
    library("ggplot2") +library("extrafont") +extrafont::loadfonts()
    #> ETBembo already registered with pdfFonts().
    +p <- ggplot(mtcars, aes(factor(cyl), mpg)) +# with a point for the median and lines for whiskers +p + geom_tufteboxplot()
    # with a line for the interquartile range and points for whiskers +p + geom_tufteboxplot(median.type = "line", whisker.type = "point", hoffset = 0)
    # with a wide line for the interquartile range and lines for whiskers +p + geom_tufteboxplot(median.type = "line", hoffset = 0, width = 3)
    #> Warning: position_dodge requires non-overlapping x intervals
    # with an offset line for the interquartile range and lines for whiskers +p + geom_tufteboxplot(median.type = "line")
    # combined with theme_tufte +p + geom_tufteboxplot() + + theme_tufte() + + theme(axis.ticks.x = element_blank())
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/import_et_book.html b/docs/reference/import_et_book.html new file mode 100644 index 0000000..766329c --- /dev/null +++ b/docs/reference/import_et_book.html @@ -0,0 +1,178 @@ + + + + + + + + +Import ET Book font for use in plots — import_et_book • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    There is an option ggtufte.loadfonts which -- if set to TRUE -- will +call extrafont::loadfonts() to register non-core fonts with R PDF & PostScript +devices. If you are running under Windows, the package calls the same function +to register non-core fonts with the Windows graphics device.

    + +
    + +
    import_et_book()
    + +

    Source

    + +

    https://github.com/edwardtufte/et-book

    + +

    Note

    + +

    This will take care of ensuring PDF/PostScript usage. The location of the +font directory is displayed after the base import is complete. It is highly +recommended that you install them on your system the same way you would any +other font you wish to use in other programs.

    + +

    References

    + +

    https://edwardtufte.github.io/et-book/

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/index.html b/docs/reference/index.html new file mode 100644 index 0000000..0cf746a --- /dev/null +++ b/docs/reference/index.html @@ -0,0 +1,209 @@ + + + + + + + + +Function reference • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    All functions

    +

    +
    +

    font_et

    +

    ET Book fonts R variable aliases

    +

    geom_rangeframe()

    +

    Range Frames

    +

    geom_tufteboxplot()

    +

    Tufte's Box Plot

    +

    import_et_book()

    +

    Import ET Book font for use in plots

    +

    extended_range_breaks_() extended_range_breaks()

    +

    Pretty axis breaks inclusive of extreme values

    +

    smart_digits() smart_digits_format()

    +

    Format numbers with automatic number of digits

    +

    stat_fivenumber()

    +

    Calculate components of a five-number summary

    +

    theme_tufte()

    +

    Tufte Maximal Data, Minimal Ink Theme

    +

    tufte_theme_fonts

    +

    Font options to use with the Tufte Theme

    +
    + + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/range_breaks.html b/docs/reference/range_breaks.html new file mode 100644 index 0000000..a3802b2 --- /dev/null +++ b/docs/reference/range_breaks.html @@ -0,0 +1,213 @@ + + + + + + + + +Pretty axis breaks inclusive of extreme values — extended_range_breaks_ • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    This function returns pretty axis breaks that always include the extreme values of the data. +This works by calling the extended Wilkinson algorithm (Talbot et. al, 2010), constrained to solutions interior to the data range. +Then, the minimum and maximum labels are moved to the minimum and maximum of the data range.

    + +
    + +
    extended_range_breaks_(dmin, dmax, n = 5, Q = c(1, 5, 2, 2.5, 4, 3),
    +  w = c(0.25, 0.2, 0.5, 0.05))
    +
    +extended_range_breaks(n = 5, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + +
    dmin

    minimum of the data range

    dmax

    maximum of the data range

    n

    desired number of breaks

    Q

    set of nice numbers

    w

    weights applied to the four optimization components (simplicity, coverage, density, and legibility)

    ...

    other arguments passed to extended_range_breaks_

    + +

    Value

    + +

    For extended_range_breaks, the vector of axis label locations. +For scales_extended_range_breaks, a function which takes a single argument, a vector of data, and returns the vector of axis label locations.

    +

    A function which returns breaks given a vector.

    + +

    Details

    + +

    extended_range_breaks implements the algorithm and returns the break values. +scales_extended_range_breaks uses the conventions of the scales package, and returns a function.

    + +

    References

    + +

    Talbot, J., Lin, S., Hanrahan, P. (2010) An Extension of Wilkinson's Algorithm for Positioning Tick Labels on Axes, InfoVis 2010.

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/smart_digits.html b/docs/reference/smart_digits.html new file mode 100644 index 0000000..f3029e6 --- /dev/null +++ b/docs/reference/smart_digits.html @@ -0,0 +1,184 @@ + + + + + + + + +Format numbers with automatic number of digits — smart_digits • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Format numbers with automatic number of digits

    + +
    + +
    smart_digits(x, ...)
    +
    +smart_digits_format(x, ...)
    + +

    Arguments

    + + + + + + + + + + +
    x

    A numeric vector to format

    ...

    Parameters passed to format

    + +

    Value

    + +

    smart_digits returns a character vector. +smart_digits_format returns a function with a single argument x, a numeric vector, that returns a character vector.

    + +

    References

    + +

    Josh O'Brien, http://stackoverflow.com/questions/23169938/select-accuracy-to-display-additional-axis-breaks/23171858#23171858.

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/stat_fivenumber.html b/docs/reference/stat_fivenumber.html new file mode 100644 index 0000000..c05d93f --- /dev/null +++ b/docs/reference/stat_fivenumber.html @@ -0,0 +1,240 @@ + + + + + + + + +Calculate components of a five-number summary — stat_fivenumber • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    The five number summary of a sample is the minimum, first quartile, +median, third quartile, and maximum.

    + +
    + +
    stat_fivenumber(mapping = NULL, data = NULL, geom = "boxplot", qs = c(0,
    +  0.25, 0.5, 0.75, 1), na.rm = FALSE, position = "identity",
    +  show.legend = NA, inherit.aes = TRUE, ...)
    + +

    Arguments

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    mapping

    Set of aesthetic mappings created by aes() or +aes_(). If specified and inherit.aes = TRUE (the +default), it is combined with the default mapping at the top level of the +plot. You must supply mapping if there is no plot mapping.

    data

    The data to be displayed in this layer. There are three +options:

    +

    If NULL, the default, the data is inherited from the plot +data as specified in the call to ggplot().

    +

    A data.frame, or other object, will override the plot +data. All objects will be fortified to produce a data frame. See +fortify() for which variables will be created.

    +

    A function will be called with a single argument, +the plot data. The return value must be a data.frame., and +will be used as the layer data.

    geom

    The geometric object to use display the data

    qs

    Quantiles to use for the five number summary.

    na.rm

    If FALSE (the default), removes missing values with +a warning. If TRUE silently removes missing values.

    position

    Position adjustment, either as a string, or the result of +a call to a position adjustment function.

    show.legend

    logical. Should this layer be included in the legends? +NA, the default, includes if any aesthetics are mapped. +FALSE never includes, and TRUE always includes. +It can also be a named logical vector to finely select the aesthetics to +display.

    inherit.aes

    If FALSE, overrides the default aesthetics, +rather than combining with them. This is most useful for helper functions +that define both data and aesthetics and shouldn't inherit behaviour from +the default plot specification, e.g. borders().

    ...

    Other arguments passed on to layer(). These are +often aesthetics, used to set an aesthetic to a fixed value, like +color = "red" or size = 3. They may also be parameters +to the paired geom/stat.

    + +

    Value

    + +

    A data frame with additional columns:

    +
    width

    width of boxplot

    +
    min

    minimum

    +
    lower

    lower hinge, 25% quantile

    +
    middle

    median, 50% quantile

    +
    upper

    upper hinge, 75% quantile

    +
    max

    maximum

    + + +

    See also

    + +

    stat_boxplot

    + + +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/theme_tufte-1.png b/docs/reference/theme_tufte-1.png new file mode 100644 index 0000000..89917f5 Binary files /dev/null and b/docs/reference/theme_tufte-1.png differ diff --git a/docs/reference/theme_tufte-2.png b/docs/reference/theme_tufte-2.png new file mode 100644 index 0000000..d5159b1 Binary files /dev/null and b/docs/reference/theme_tufte-2.png differ diff --git a/docs/reference/theme_tufte.html b/docs/reference/theme_tufte.html new file mode 100644 index 0000000..949f234 --- /dev/null +++ b/docs/reference/theme_tufte.html @@ -0,0 +1,213 @@ + + + + + + + + +Tufte Maximal Data, Minimal Ink Theme — theme_tufte • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    Theme based on Chapter 6 'Data-Ink Maximization and Graphical +Design' of Edward Tufte *The Visual Display of Quantitative +Information*. No border, no axis lines, no grids. This theme works +best in combination with geom_rug or +geom_rangeframe.

    + +
    + +
    theme_tufte(base_size = 11,
    +  base_family = extrafont::choose_font(ggtufte::tufte_theme_fonts),
    +  ticks = TRUE)
    + +

    Arguments

    + + + + + + + + + + + + + + +
    base_size

    base font size

    base_family

    base font family

    ticks

    logical Show axis ticks?

    + +

    Note

    + +

    The default font family is set to 'serif' as he uses serif fonts +for labels in 'The Visual Display of Quantitative Information'. +The serif font used by Tufte in his books is a variant of Bembo, +while the sans serif font is Gill Sans. If these fonts are +installed on your system, then you can use them with the package +extrafont.

    + +

    References

    + +

    Tufte, Edward R. (2001) The Visual Display of +Quantitative Information, Chapter 6.

    + + +

    Examples

    +
    library("ggplot2") +library("extrafont") +extrafont::loadfonts()
    #> ETBembo already registered with pdfFonts().
    +p <- ggplot(mtcars, aes(x = wt, y = mpg)) + + geom_point() + + scale_x_continuous(breaks = extended_range_breaks()(mtcars$wt)) + + scale_y_continuous(breaks = extended_range_breaks()(mtcars$mpg)) + + ggtitle("Cars") + +p + geom_rangeframe() + + theme_tufte()
    +p + geom_rug() + + theme_tufte(ticks = FALSE)
    +
    + +
    + +
    + + +
    +

    Site built with pkgdown.

    +
    + +
    +
    + + + + + + diff --git a/docs/reference/tufte_theme_fonts.html b/docs/reference/tufte_theme_fonts.html new file mode 100644 index 0000000..47064ee --- /dev/null +++ b/docs/reference/tufte_theme_fonts.html @@ -0,0 +1,174 @@ + + + + + + + + +Font options to use with the Tufte Theme — tufte_theme_fonts • ggtufte + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + +
    + +
    +
    + + +
    + +

    List of font or font-families to use with theme_tufte. +It starts with the preferred ETBembo font used in Tufte's book along with +fallback options.

    + +
    + +
    tufte_theme_fonts
    + +

    Format

    + +

    A character vector.

    + +

    Details

    + +

    This list is derived from the list of fonts used in +https://github.com/edwardtufte/tufte-css

    + + +

    Examples

    +
    tufte_theme_fonts
    #> [1] "ETBembo RomanLF" "Palatino" "Palatino Linotype" +#> [4] "Palatino LT STD" "Book Antiqua" "Georgia" +#> [7] "serif"
    +
    + +
    + + +
    + + + + + + diff --git a/examples/ex-geom_tufteboxplot.R b/examples/ex-geom_quartileplot.R similarity index 68% rename from examples/ex-geom_tufteboxplot.R rename to examples/ex-geom_quartileplot.R index 9f3d214..d51cb8e 100644 --- a/examples/ex-geom_tufteboxplot.R +++ b/examples/ex-geom_quartileplot.R @@ -4,14 +4,14 @@ extrafont::loadfonts() p <- ggplot(mtcars, aes(factor(cyl), mpg)) # with a point for the median and lines for whiskers -p + geom_tufteboxplot() +p + geom_quartileplot() # with a line for the interquartile range and points for whiskers -p + geom_tufteboxplot(median.type = "line", whisker.type = "point", hoffset = 0) +p + geom_quartileplot(median.type = "line", whisker.type = "point", hoffset = 0) # with a wide line for the interquartile range and lines for whiskers -p + geom_tufteboxplot(median.type = "line", hoffset = 0, width = 3) +p + geom_quartileplot(median.type = "line", hoffset = 0, width = 3) # with an offset line for the interquartile range and lines for whiskers -p + geom_tufteboxplot(median.type = "line") +p + geom_quartileplot(median.type = "line") # combined with theme_tufte -p + geom_tufteboxplot() + +p + geom_quartileplot() + theme_tufte() + theme(axis.ticks.x = element_blank()) diff --git a/examples/ex-theme_tufte.R b/examples/ex-theme_tufte.R index 02aa85c..c74059b 100644 --- a/examples/ex-theme_tufte.R +++ b/examples/ex-theme_tufte.R @@ -4,8 +4,8 @@ extrafont::loadfonts() p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + - scale_x_continuous(breaks = extended_range_breaks()(mtcars$wt)) + - scale_y_continuous(breaks = extended_range_breaks()(mtcars$mpg)) + + scale_x_continuous(breaks = pretty_range_breaks(mtcars$wt, 5)) + + scale_y_continuous(breaks = pretty_range_breaks(mtcars$mpg, 5)) + ggtitle("Cars") p + geom_rangeframe() + diff --git a/inst/COPYRIGHTS b/inst/COPYRIGHTS index bd26e78..e89b1b4 100644 --- a/inst/COPYRIGHTS +++ b/inst/COPYRIGHTS @@ -2,7 +2,7 @@ All R source code files are released under the MIT license. ----------------------------- -ET Book font has the following license/copyright: +ETBembo fonts have the following license/copyright: Copyright (c) 2015 Dmitry Krasny, Bonnie Scranton, Edward Tufte. @@ -11,3 +11,99 @@ Permission is hereby granted, free of charge, to any person obtaining a copy of The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Lato fonts have the following license/copyright: + +Copyright (c) 2010-2015, Łukasz Dziedzic (dziedzic@typoland.com), +with Reserved Font Name Lato. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/inst/fonts/ETBembo/LICENSE.txt b/inst/fonts/ETBembo/LICENSE.txt new file mode 100644 index 0000000..f1c825e --- /dev/null +++ b/inst/fonts/ETBembo/LICENSE.txt @@ -0,0 +1,7 @@ +Copyright (c) 2015 Dmitry Krasny, Bonnie Scranton, Edward Tufte. + +Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. diff --git a/inst/fonts/et-book-display-italic-old-style-figures.ttf b/inst/fonts/ETBembo/et-book-display-italic-old-style-figures.ttf similarity index 100% rename from inst/fonts/et-book-display-italic-old-style-figures.ttf rename to inst/fonts/ETBembo/et-book-display-italic-old-style-figures.ttf diff --git a/inst/fonts/et-book-roman-old-style-figures.ttf b/inst/fonts/ETBembo/et-book-roman-old-style-figures.ttf similarity index 100% rename from inst/fonts/et-book-roman-old-style-figures.ttf rename to inst/fonts/ETBembo/et-book-roman-old-style-figures.ttf diff --git a/inst/fonts/et-book-semi-bold-old-style-figures.ttf b/inst/fonts/ETBembo/et-book-semi-bold-old-style-figures.ttf similarity index 100% rename from inst/fonts/et-book-semi-bold-old-style-figures.ttf rename to inst/fonts/ETBembo/et-book-semi-bold-old-style-figures.ttf diff --git a/inst/fonts/Lato/Lato-Bold.ttf b/inst/fonts/Lato/Lato-Bold.ttf new file mode 100644 index 0000000..ef5ae3b Binary files /dev/null and b/inst/fonts/Lato/Lato-Bold.ttf differ diff --git a/inst/fonts/Lato/Lato-Italic.ttf b/inst/fonts/Lato/Lato-Italic.ttf new file mode 100644 index 0000000..b23256f Binary files /dev/null and b/inst/fonts/Lato/Lato-Italic.ttf differ diff --git a/inst/fonts/Lato/Lato-Regular.ttf b/inst/fonts/Lato/Lato-Regular.ttf new file mode 100644 index 0000000..adbfc46 Binary files /dev/null and b/inst/fonts/Lato/Lato-Regular.ttf differ diff --git a/inst/fonts/Lato/OFL.txt b/inst/fonts/Lato/OFL.txt new file mode 100755 index 0000000..6d2c416 --- /dev/null +++ b/inst/fonts/Lato/OFL.txt @@ -0,0 +1,94 @@ +Copyright (c) 2010-2015, Łukasz Dziedzic (dziedzic@typoland.com), +with Reserved Font Name Lato. + +This Font Software is licensed under the SIL Open Font License, Version 1.1. +This license is copied below, and is also available with a FAQ at: +http://scripts.sil.org/OFL + + +----------------------------------------------------------- +SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007 +----------------------------------------------------------- + +PREAMBLE +The goals of the Open Font License (OFL) are to stimulate worldwide +development of collaborative font projects, to support the font creation +efforts of academic and linguistic communities, and to provide a free and +open framework in which fonts may be shared and improved in partnership +with others. + +The OFL allows the licensed fonts to be used, studied, modified and +redistributed freely as long as they are not sold by themselves. The +fonts, including any derivative works, can be bundled, embedded, +redistributed and/or sold with any software provided that any reserved +names are not used by derivative works. The fonts and derivatives, +however, cannot be released under any other type of license. The +requirement for fonts to remain under this license does not apply +to any document created using the fonts or their derivatives. + +DEFINITIONS +"Font Software" refers to the set of files released by the Copyright +Holder(s) under this license and clearly marked as such. This may +include source files, build scripts and documentation. + +"Reserved Font Name" refers to any names specified as such after the +copyright statement(s). + +"Original Version" refers to the collection of Font Software components as +distributed by the Copyright Holder(s). + +"Modified Version" refers to any derivative made by adding to, deleting, +or substituting -- in part or in whole -- any of the components of the +Original Version, by changing formats or by porting the Font Software to a +new environment. + +"Author" refers to any designer, engineer, programmer, technical +writer or other person who contributed to the Font Software. + +PERMISSION & CONDITIONS +Permission is hereby granted, free of charge, to any person obtaining +a copy of the Font Software, to use, study, copy, merge, embed, modify, +redistribute, and sell modified and unmodified copies of the Font +Software, subject to the following conditions: + +1) Neither the Font Software nor any of its individual components, +in Original or Modified Versions, may be sold by itself. + +2) Original or Modified Versions of the Font Software may be bundled, +redistributed and/or sold with any software, provided that each copy +contains the above copyright notice and this license. These can be +included either as stand-alone text files, human-readable headers or +in the appropriate machine-readable metadata fields within text or +binary files as long as those fields can be easily viewed by the user. + +3) No Modified Version of the Font Software may use the Reserved Font +Name(s) unless explicit written permission is granted by the corresponding +Copyright Holder. This restriction only applies to the primary font name as +presented to the users. + +4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font +Software shall not be used to promote, endorse or advertise any +Modified Version, except to acknowledge the contribution(s) of the +Copyright Holder(s) and the Author(s) or with their explicit written +permission. + +5) The Font Software, modified or unmodified, in part or in whole, +must be distributed entirely under this license, and must not be +distributed under any other license. The requirement for fonts to +remain under this license does not apply to any document created +using the Font Software. + +TERMINATION +This license becomes null and void if any of the above conditions are +not met. + +DISCLAIMER +THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT +OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE +COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL +DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM +OTHER DEALINGS IN THE FONT SOFTWARE. diff --git a/man/ETBembo.Rd b/man/ETBembo.Rd index ab3b137..29503a4 100644 --- a/man/ETBembo.Rd +++ b/man/ETBembo.Rd @@ -21,6 +21,10 @@ ET Book (ETBembo font-family) comprises five fonts: \item \code{"ETBembo BoldLF"}: Bold (lining figures) \item \code{"ETBembo DisplayItalic"}: Display Italic (oldstyle figures) } + +For headings, the sans serif font, Gill Sans is used. +Since there is no Gill Sans variant with an open license, the similar +Lato font is included with this package. } \examples{ font_et diff --git a/man/geom_tufteboxplot.Rd b/man/geom_quartileplot.Rd similarity index 53% rename from man/geom_tufteboxplot.Rd rename to man/geom_quartileplot.Rd index 9a588aa..85752ca 100644 --- a/man/geom_tufteboxplot.Rd +++ b/man/geom_quartileplot.Rd @@ -1,16 +1,15 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/geom-tufteboxplot.R \docType{data} -\name{geom_tufteboxplot} -\alias{geom_tufteboxplot} -\alias{GeomTufteboxplot} -\title{Tufte's Box Plot} +\name{geom_quartileplot} +\alias{geom_quartileplot} +\alias{GeomQuartilePlot} +\title{A box and whisker's plot (in the style of Tufte)} \usage{ -geom_tufteboxplot(mapping = NULL, data = NULL, stat = "fivenumber", - position = "dodge", outlier.colour = "black", outlier.shape = 19, - outlier.size = 1.5, outlier.stroke = 0.5, voffset = 0.01, - hoffset = 0.005, na.rm = FALSE, show.legend = NA, inherit.aes = TRUE, - median.type = "point", whisker.type = "line", ...) +geom_quartileplot(mapping = NULL, data = NULL, stat = "fivenumber", + position = "dodge", na.rm = FALSE, show.legend = NA, + inherit.aes = TRUE, middle.line = FALSE, whisker.line = TRUE, + hoffset = 0.01, fatten = 1, gapsize = 0.01, ...) } \arguments{ \item{mapping}{Set of aesthetic mappings created by \code{\link[=aes]{aes()}} or @@ -38,22 +37,6 @@ layer, as a string.} \item{position}{Position adjustment, either as a string, or the result of a call to a position adjustment function.} -\item{outlier.colour}{colour for outlying points} - -\item{outlier.shape}{shape of outlying points} - -\item{outlier.size}{size of outlying points} - -\item{outlier.stroke}{stroke for outlying points} - -\item{voffset}{controls the size of the gap in the line representing the -median when \code{median.type = 'line'}. This is a fraction of the range -of \code{y}.} - -\item{hoffset}{controls how much the interquartile line is offset from the -whiskers when \code{median.type = 'line'}. This is a fraction of the -range of \code{x}.} - \item{na.rm}{If \code{FALSE}, the default, missing values are removed with a warning. If \code{TRUE}, missing values are silently removed.} @@ -68,48 +51,37 @@ rather than combining with them. This is most useful for helper functions that define both data and aesthetics and shouldn't inherit behaviour from the default plot specification, e.g. \code{\link[=borders]{borders()}}.} -\item{median.type}{If \code{'point'}, then the median is represented by a -point, and the interquartile range by a gap in the line. If -\code{median.type='line'}, then the interquartile range is represented by -a line, possibly offset, and the median by a gap in the line.} - -\item{whisker.type}{If \code{'line'}, then whiskers are represented by lines. -If \code{'point'}, then whiskers are represented by points at -\code{ymin} and \code{ymax}.} - \item{...}{Other arguments passed on to \code{\link[=layer]{layer()}}. These are often aesthetics, used to set an aesthetic to a fixed value, like \code{color = "red"} or \code{size = 3}. They may also be parameters to the paired geom/stat.} } \description{ -Edward Tufte's revisions of the box plot as described in -\emph{The Visual Display of Quantitative Information}. -This functions provides several box plot variants: -\itemize{ -\item{A point indicating the median, a gap indicating the - interquartile range, and lines for whiskers.} -\item{An offset line indicating the interquartile range - and a gap indicating the median.} -\item{A line indicating the interquartile range, - a gap indicating the median, and points indicating - the minimum and maximum values} -\item{A wide line indicating the interquartile range, - a gap indicating the median, and lines indicating the minimum and - maximum.} +Tufte \emph{The Visual Display of Quantitative Information} (Ch 6) +proposes several revisions of the box plot. +These variants compactly display the distribution of a continuous variable. +It visualises five summary statistics: the median, two hinges (25\% and 75\% quartiles) +and two whiskers (minimum, maximum). } +\details{ +The statistics are different than \code{\link{geom_boxplot}}. } \section{Aesthetics}{ \itemize{ -\item x [required] -\item y [required] -\item colour -\item size -\item linetype -\item shape -\item fill -\item alpha + \item x (required) x coordinate of the line + \item upper + \item lower + \item middle + \item ymin + \item ymax + \item colour (required) + \item size thickness of the lines + \item linetype types of the lines + \item width + \item shape shape of the point(s) + \item fill fill of the point(s) + \item alpha transparency } } @@ -120,28 +92,27 @@ extrafont::loadfonts() p <- ggplot(mtcars, aes(factor(cyl), mpg)) # with a point for the median and lines for whiskers -p + geom_tufteboxplot() +p + geom_quartileplot() # with a line for the interquartile range and points for whiskers -p + geom_tufteboxplot(median.type = "line", whisker.type = "point", hoffset = 0) +p + geom_quartileplot(median.type = "line", whisker.type = "point", hoffset = 0) # with a wide line for the interquartile range and lines for whiskers -p + geom_tufteboxplot(median.type = "line", hoffset = 0, width = 3) +p + geom_quartileplot(median.type = "line", hoffset = 0, width = 3) # with an offset line for the interquartile range and lines for whiskers -p + geom_tufteboxplot(median.type = "line") +p + geom_quartileplot(median.type = "line") # combined with theme_tufte -p + geom_tufteboxplot() + +p + geom_quartileplot() + theme_tufte() + theme(axis.ticks.x = element_blank()) } \references{ Tufte, Edward R. (2001) The Visual Display of -Quantitative Information, Chapter 6. - -McGill, R., Tukey, J. W. and Larsen, W. A. (1978) Variations of -box plots. The American Statistician 32, 12-16. + Quantitative Information, Chapter 6. } \seealso{ \code{\link{geom_boxplot}} +\code{\link{geom_boxplot}} and \code{\link{geom_pointrange}}. + Other geom tufte: \code{\link{geom_rangeframe}} } \keyword{datasets} diff --git a/man/geom_rangeframe.Rd b/man/geom_rangeframe.Rd index 0da106a..0629e35 100644 --- a/man/geom_rangeframe.Rd +++ b/man/geom_rangeframe.Rd @@ -87,6 +87,6 @@ Tufte, Edward R. (2001) The Visual Display of Quantitative Information, Chapter 6. } \seealso{ -Other geom tufte: \code{\link{geom_tufteboxplot}} +Other geom tufte: \code{\link{geom_quartileplot}} } \keyword{datasets} diff --git a/man/import_et_book.Rd b/man/import_ggtufte_fonts.Rd similarity index 91% rename from man/import_et_book.Rd rename to man/import_ggtufte_fonts.Rd index 2fdf037..c2a61c7 100644 --- a/man/import_et_book.Rd +++ b/man/import_ggtufte_fonts.Rd @@ -1,13 +1,13 @@ % Generated by roxygen2: do not edit by hand % Please edit documentation in R/et-book.R -\name{import_et_book} -\alias{import_et_book} +\name{import_ggtufte_fonts} +\alias{import_ggtufte_fonts} \title{Import ET Book font for use in plots} \source{ \url{https://github.com/edwardtufte/et-book} } \usage{ -import_et_book() +import_ggtufte_fonts() } \description{ There is an option \code{ggtufte.loadfonts} which -- if set to \code{TRUE} -- will diff --git a/man/range_breaks.Rd b/man/range_breaks.Rd index 6ee2368..b0f6e2e 100644 --- a/man/range_breaks.Rd +++ b/man/range_breaks.Rd @@ -1,43 +1,30 @@ % Generated by roxygen2: do not edit by hand -% Please edit documentation in R/extended_range_breaks.R -\name{extended_range_breaks_} -\alias{extended_range_breaks_} -\alias{extended_range_breaks} +% Please edit documentation in R/range_breaks.R +\name{range_breaks} +\alias{range_breaks} \title{Pretty axis breaks inclusive of extreme values} \usage{ -extended_range_breaks_(dmin, dmax, n = 5, Q = c(1, 5, 2, 2.5, 4, 3), - w = c(0.25, 0.2, 0.5, 0.05)) - -extended_range_breaks(n = 5, ...) +range_breaks(x, n = 5, Q = c(1, 5, 2, 2.5, 4, 3), w = c(0.25, 0.2, 0.5, + 0.05)) } \arguments{ -\item{dmin}{minimum of the data range} - -\item{dmax}{maximum of the data range} +\item{x}{Vector of numeric values} \item{n}{desired number of breaks} \item{Q}{set of nice numbers} \item{w}{weights applied to the four optimization components (simplicity, coverage, density, and legibility)} - -\item{...}{other arguments passed to \code{extended_range_breaks_}} } \value{ -For \code{extended_range_breaks}, the vector of axis label locations. -For \code{scales_extended_range_breaks}, a function which takes a single argument, a vector of data, and returns the vector of axis label locations. - -A function which returns breaks given a vector. +For \code{range_breaks}, a function which takes a single argument, + a vector of data, which returns the vector of axis label locations. } \description{ This function returns pretty axis breaks that always include the extreme values of the data. This works by calling the extended Wilkinson algorithm (Talbot et. al, 2010), constrained to solutions interior to the data range. Then, the minimum and maximum labels are moved to the minimum and maximum of the data range. } -\details{ -\code{extended_range_breaks} implements the algorithm and returns the break values. -\code{scales_extended_range_breaks} uses the conventions of the \pkg{scales} package, and returns a function. -} \references{ Talbot, J., Lin, S., Hanrahan, P. (2010) An Extension of Wilkinson's Algorithm for Positioning Tick Labels on Axes, InfoVis 2010. } diff --git a/man/smart_digits.Rd b/man/smart_digits.Rd deleted file mode 100644 index 8a73969..0000000 --- a/man/smart_digits.Rd +++ /dev/null @@ -1,29 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/extended_range_breaks.R -\name{smart_digits} -\alias{smart_digits} -\alias{smart_digits_format} -\title{Format numbers with automatic number of digits} -\usage{ -smart_digits(x, ...) - -smart_digits_format(x, ...) -} -\arguments{ -\item{x}{A numeric vector to format} - -\item{...}{Parameters passed to \code{\link{format}}} -} -\value{ -\code{smart_digits} returns a character vector. -\code{smart_digits_format} returns a function with a single argument \code{x}, a numeric vector, that returns a character vector. -} -\description{ -Format numbers with automatic number of digits -} -\references{ -Josh O'Brien, \url{http://stackoverflow.com/questions/23169938/select-accuracy-to-display-additional-axis-breaks/23171858#23171858}. -} -\author{ -Josh O'Brien, Baptise Auguie, Jeffrey B. Arnold -} diff --git a/man/theme_tufte.Rd b/man/theme_tufte.Rd index 56b0d70..5feccdc 100644 --- a/man/theme_tufte.Rd +++ b/man/theme_tufte.Rd @@ -2,34 +2,22 @@ % Please edit documentation in R/tufte.R \name{theme_tufte} \alias{theme_tufte} -\title{Tufte Maximal Data, Minimal Ink Theme} +\title{Tufte's Maximal Data, Minimal Ink Theme} \usage{ -theme_tufte(base_size = 11, - base_family = extrafont::choose_font(ggtufte::tufte_theme_fonts), - ticks = TRUE) +theme_tufte(base_size = 11, ticks = TRUE) } \arguments{ \item{base_size}{base font size} -\item{base_family}{base font family} - \item{ticks}{\code{logical} Show axis ticks?} } \description{ Theme based on Chapter 6 'Data-Ink Maximization and Graphical -Design' of Edward Tufte *The Visual Display of Quantitative -Information*. No border, no axis lines, no grids. This theme works -best in combination with \code{\link{geom_rug}} or +Design' of Tufte \emph{The Visual Display of Quantitative Information}. +No border, no axis lines, no grids. This theme works +well in combination with \code{\link{geom_rug}} or \code{\link{geom_rangeframe}}. } -\note{ -The default font family is set to 'serif' as he uses serif fonts -for labels in 'The Visual Display of Quantitative Information'. -The serif font used by Tufte in his books is a variant of Bembo, -while the sans serif font is Gill Sans. If these fonts are -installed on your system, then you can use them with the package -\bold{extrafont}. -} \examples{ library("ggplot2") library("extrafont") @@ -37,8 +25,8 @@ extrafont::loadfonts() p <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + - scale_x_continuous(breaks = extended_range_breaks()(mtcars$wt)) + - scale_y_continuous(breaks = extended_range_breaks()(mtcars$mpg)) + + scale_x_continuous(breaks = pretty_range_breaks(mtcars$wt, 5)) + + scale_y_continuous(breaks = pretty_range_breaks(mtcars$mpg, 5)) + ggtitle("Cars") p + geom_rangeframe() + diff --git a/man/tufte_theme_fonts.Rd b/man/tufte_theme_fonts.Rd deleted file mode 100644 index 85c524e..0000000 --- a/man/tufte_theme_fonts.Rd +++ /dev/null @@ -1,23 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/tufte.R -\docType{data} -\name{tufte_theme_fonts} -\alias{tufte_theme_fonts} -\title{Font options to use with the Tufte Theme} -\format{A character vector.} -\usage{ -tufte_theme_fonts -} -\description{ -List of font or font-families to use with \code{theme_tufte}. -It starts with the preferred ETBembo font used in Tufte's book along with -fallback options. -} -\details{ -This list is derived from the list of fonts used in -\href{tufte-css}{https://github.com/edwardtufte/tufte-css} -} -\examples{ -tufte_theme_fonts -} -\keyword{datasets} diff --git a/tests/testthat/test-geom_tufteboxplot.R b/tests/testthat/test-geom_tufteboxplot.R index df851c2..117a422 100644 --- a/tests/testthat/test-geom_tufteboxplot.R +++ b/tests/testthat/test-geom_tufteboxplot.R @@ -1,5 +1,5 @@ -context("geom_tufteboxplot") +context("geom_quartileplot") -test_that("geom_tufteboxplot works", { +test_that("geom_quartileplot works", { expect_is(geom_rangeframe(), "LayerInstance") }) diff --git a/tests/testthat/test-range_frame.R b/tests/testthat/test-range_frame.R new file mode 100644 index 0000000..fe18c91 --- /dev/null +++ b/tests/testthat/test-range_frame.R @@ -0,0 +1,10 @@ +context("range_frame") + +test_that("range_breaks works", { + f <- range_breaks(5) + expect_is(f, "function") + x <- 1:20 + out <- f(x) + expect_equal(min(out), min(x)) + expect_equal(max(out), max(x)) +}) \ No newline at end of file diff --git a/vignettes/intro.Rmd b/vignettes/intro.Rmd index 29866d2..1bb30dc 100644 --- a/vignettes/intro.Rmd +++ b/vignettes/intro.Rmd @@ -28,20 +28,133 @@ options(htmltools.dir.version = FALSE) ```{r} library("ggplot2") library("ggtufte") -extrafont::loadfonts() +library("scales") +extrafont::loadfonts(quiet = TRUE) + +``` + +## Scatter plots + +```{r} +p <- ggplot(mtcars, aes(wt, mpg)) + geom_point() +``` + +```{r} +p + theme_bw() +``` + +The **ggplot2** theme provided with this package, `theme_tufte`, removes most of the +ink from the plot. There are no grid-lines and no borders or axis. +```{r} +p + theme_tufte() +``` + +Instead of using axis lines the ink-to-data ratio can be improved by using the axis lines +to encode the range of the data. +The `geom_rangeframe()` will add lines representing the range of the data along the axes. +```{r} +p + theme_tufte() + + geom_rangeframe() ``` -## Minimal Bar Plot +However, the axis breaks do not match up with the range. +It would be more informative to label the minimum and maximum values of breaks. +```{r} +p + theme_tufte() + + geom_rangeframe() + + scale_y_continuous(breaks = range_breaks(), + label = format_format(digits = 1)) + + scale_x_continuous(breaks = range_breaks(), + label = format_format(digits = 1)) +``` +```{r} +p + theme_tufte() + + geom_rangeframe() + + scale_y_continuous(breaks = range_breaks()(mtcars$mpg), + labels = format_format(digits = 1)) + + scale_x_continuous(breaks = range_breaks()(mtcars$wt), + labels = format_format(digits = 1)) +``` +```{r} +p + theme_tufte(ticks = FALSE) + + geom_rug() + + scale_y_continuous(breaks = range_breaks()(mtcars$mpg), + labels = format_format(digits = 1)) + + scale_x_continuous(breaks = range_breaks()(mtcars$wt), + labels = format_format(digits = 1)) +``` -## Minimal Scatterplot with Range-Frame +## Quartile Plots +```{r} +p <- ggplot(mpg, aes(class, hwy)) + + theme(axis.ticks.x = element_blank()) +``` + +Tufte Ch. 6 proposes several redesigns of the venerable box plot. +Unlike the Tukey's boxplot, these box plots, display the five-number summary +(median, 25% quartile, 75% quartile, maximum, minimum), instead of the +stats and outliers calculated in Tukey's boxplot. + +This displays the standard box plot in **ggplot2**. +```{r} +p + geom_boxplot(stat = StatFivenumber) +``` +I use the `StatFivenumber` stat to calculate the fiver-number summary rather +than the summary used in the boxplot. + +@Tufte calls his redesign a *quartile-plot*. +The function `geom_quartileplot()` implements these. + +The first redesign erases the box from the boxplot. +The whiskers remain, negative space represents the interquartile and a point represents the median. +```{r} +p + geom_quartileplot() +``` + +A second alternative is to invert the first. +Points are used to represent the minimum and maximum, a line for the interquartile +range, and a gap in the line to represent the median. +```{r} +p + geom_quartileplot(whisker.line = FALSE, middle.line = TRUE) +``` + +A third alternative is to use a line to represent the range, and a gap to +represent the median. +The interquartile range is represented by a thicker section of line. +```{r} +p + geom_quartileplot(whisker.line = TRUE, middle.line = TRUE, + hoffset = 0, fatten = 2) +``` + +A fourth alternative uses lines for the upper and lower whiskers. +The interquartile range is represented by a line offset from the first. +The median is still represented by a gap. +```{r} +p + geom_quartileplot(whisker.line = TRUE, middle.line = TRUE) +``` + +## Theme + +```{r} +p <- ggplot(mtcars, aes(x = wt, y = mpg, colour = factor(cyl))) + + geom_point() + + facet_wrap(~ am) + + labs(title = "Title", subtitle = "Subtitle", caption = "Caption") +p + theme_tufte() +``` + +```{r} +p + theme_tufte(sans_title = TRUE) +``` ## Typography + ## References - [Tufte Handout](https://rstudio.github.io/tufte/) R markdown format