Merge branch 'master' of github.com:haozhu233/kableExtra
diff --git a/NAMESPACE b/NAMESPACE
index eda523b..b8ebdd2 100644
--- a/NAMESPACE
+++ b/NAMESPACE
@@ -46,6 +46,7 @@
export(spec_font_size)
export(spec_hist)
export(spec_image)
+export(spec_line)
export(spec_popover)
export(spec_tooltip)
export(text_spec)
diff --git a/R/mini_plots.R b/R/mini_plots.R
index f34715f..8f13706 100644
--- a/R/mini_plots.R
+++ b/R/mini_plots.R
@@ -1,8 +1,8 @@
#' Helper functions to generate inline sparklines
#'
#' @description These functions helps you quickly generate sets of sparkline
-#' style plots using base R plotting system. Currently, we support histogram
-#' and boxplot. You can use them together with `column_spec` to
+#' style plots using base R plotting system. Currently, we support histogram,
+#' boxplot, and line. You can use them together with `column_spec` to
#' generate inline plot in tables. By default, this function will save images
#' in a folder called "kableExtra" and return the address of the file.
#'
@@ -12,12 +12,21 @@
#' @param res The resolution of the plot. Default is 300.
#' @param same_lim T/F. If x is a list of vectors, should all the plots be
#' plotted in the same range? Default is True.
-#' @param lim Manually specify plotting range in the form of `c(0, 10)`.
+#' @param lim,xlim,ylim Manually specify plotting range in the form of
+#' `c(0, 10)`. `lim` is used in `spec_hist` and `spec_boxplot`; `xlim`
+#' and `ylim` are used in `spec_line`.
#' @param xaxt On/Off for xaxis text
#' @param yaxt On/Off for yaxis text
#' @param ann On/Off for annotations (titles and axis titles)
#' @param col Color for the fill of the histogram bar/boxplot box.
#' @param border Color for the border.
+#' @param frame.plot On/Off for surrounding box (`spec_line` only). Default
+#' is False.
+#' @param lwd Line width for `spec_line`; within `spec_line`, the `minmax`
+#' argument defaults to use this value for `cex` for points. Default is 2.
+#' @param minmax,min,max Arguments passed to `points` to highlight minimum
+#' and maximum values in `spec_line`. If `min` or `max` are `NULL`, they
+#' default to the value of `minmax`. Set to an empty `list()` to disable.
#' @param dir Directory of where the images will be saved.
#' @param file File name. If not provided, a random name will be used
#' @param file_type Graphic device. Support `png` or `svg`. SVG is recommended
@@ -187,3 +196,117 @@
return(fig_dir_name)
}
+#' @rdname spec_hist
+#' @export
+spec_line <- function(x, y = NULL, width = 200, height = 50, res = 300,
+ same_lim = TRUE, xlim = NULL, ylim = NULL,
+ xaxt = 'n', yaxt = 'n', ann = FALSE,
+ col = "lightgray", border = NULL,
+ frame.plot = FALSE, lwd = 2,
+ minmax = list(pch = ".", cex = lwd, col = "red"),
+ min = minmax, max = minmax,
+ dir = if (is_latex()) rmd_files_dir() else tempdir(),
+ file = NULL,
+ file_type = if (is_latex()) "png" else "svg", ...) {
+ if (is.list(x)) {
+ if (same_lim) {
+ if (is.null(xlim)) {
+ xlim <- base::range(unlist(x))
+ }
+ if (is.null(ylim) && !is.null(y)) {
+ ylim <- base::range(unlist(y))
+ }
+ }
+ if (is.null(y)) {
+ y <- replicate(length(x), NULL, simplify = FALSE)
+ } else if (!is.list(y) || length(x) != length(y)) {
+ stop("'x' and 'y' are not the same length")
+ }
+ return(Map(function(x_, y_) {
+ spec_line(x = x_, y = y_,
+ width = width, height = height,
+ same_lim = same_lim, xlim = xlim, ylim = ylim,
+ xaxt = xaxt, yaxt = yaxt, ann = ann, col = col, border = border,
+ frame.plot = frame.plot, lwd = lwd,
+ minmax = minmax, min = min, max = max,
+ dir = dir, file = file, file_type = file_type, ...)
+ }, x, y))
+ }
+
+ if (is.null(y) || !length(y)) {
+ y <- x
+ x <- seq(0, 1, length.out = length(y))
+ tmp <- ylim
+ ylim <- xlim
+ xlim <- tmp
+ }
+
+ if (is.null(xlim)) {
+ xlim <- base::range(x)
+ }
+
+ if (is.null(ylim) && !is.null(y)) {
+ ylim <- base::range(y)
+ }
+
+ if (is.null(min)) min <- minmax
+ if (is.null(max)) max <- minmax
+
+ expand <- c(
+ if (!is.null(min) && length(min)) 0.96 else 1,
+ if (!is.null(max) && length(max)) 1.04 else 1)
+ xlim <- xlim * expand
+ ylim <- ylim * expand
+
+ file_type <- match.arg(file_type, c("svg", "png"))
+
+ if (!dir.exists(dir)) {
+ dir.create(dir)
+ }
+
+ if (is.null(file)) {
+ file <- file.path(dir, paste0(
+ "hist_", round(as.numeric(Sys.time()) * 1000), ".", file_type))
+ }
+
+ if (file_type == "svg") {
+ grDevices::svg(filename = file, width = width / res, height = height / res,
+ bg = 'transparent')
+ } else {
+ grDevices::png(filename = file, width = width, height = height, res = res,
+ bg = 'transparent')
+ }
+ curdev <- grDevices::dev.cur()
+ on.exit(grDevices::dev.off(curdev), add = TRUE)
+
+ graphics::par(mar = c(0, 0, 0.2, 0), lwd = lwd)
+ graphics::plot(x, y, type = "l", xlim = xlim, ylim = ylim, border = border,
+ xaxt = xaxt, yaxt = yaxt, ann = ann, col = col,
+ frame.plot = frame.plot, ...)
+
+ if (!is.null(min) && length(min)) {
+ ind <- which.min(y)
+ do.call(graphics::points, c(list(x[ind], y[ind]), min))
+ }
+
+ if (!is.null(max) && length(max)) {
+ ind <- which.max(y)
+ do.call(graphics::points, c(list(x[ind], y[ind]), max))
+ }
+
+ grDevices::dev.off(curdev)
+
+ if (file_type == "svg") {
+ svg_xml <- xml2::read_xml(file)
+ svg_text <- as.character(svg_xml)
+ unlink(file)
+ } else {
+ svg_text <- NULL
+ }
+ out <- list(path = file, dev = file_type, type = "line",
+ width = width, height = height, res = res,
+ svg_text = svg_text)
+
+ class(out) <- "kableExtraInlinePlots"
+ return(out)
+}
diff --git a/man/spec_hist.Rd b/man/spec_hist.Rd
index 9deb046..cfdeed3 100644
--- a/man/spec_hist.Rd
+++ b/man/spec_hist.Rd
@@ -3,6 +3,7 @@
\name{spec_hist}
\alias{spec_hist}
\alias{spec_boxplot}
+\alias{spec_line}
\title{Helper functions to generate inline sparklines}
\usage{
spec_hist(
@@ -46,6 +47,31 @@
file_type = if (is_latex()) "png" else "svg",
...
)
+
+spec_line(
+ x,
+ y = NULL,
+ width = 200,
+ height = 50,
+ res = 300,
+ same_lim = TRUE,
+ xlim = NULL,
+ ylim = NULL,
+ xaxt = "n",
+ yaxt = "n",
+ ann = FALSE,
+ col = "lightgray",
+ border = NULL,
+ frame.plot = FALSE,
+ lwd = 2,
+ minmax = list(pch = ".", cex = lwd, col = "red"),
+ min = minmax,
+ max = minmax,
+ dir = if (is_latex()) rmd_files_dir() else tempdir(),
+ file = NULL,
+ file_type = if (is_latex()) "png" else "svg",
+ ...
+)
}
\arguments{
\item{x}{Vector of values or List of vectors of values.}
@@ -76,7 +102,9 @@
\item{same_lim}{T/F. If x is a list of vectors, should all the plots be
plotted in the same range? Default is True.}
-\item{lim}{Manually specify plotting range in the form of \code{c(0, 10)}.}
+\item{lim, xlim, ylim}{Manually specify plotting range in the form of
+\code{c(0, 10)}. \code{lim} is used in \code{spec_hist} and \code{spec_boxplot}; \code{xlim}
+and \code{ylim} are used in \code{spec_line}.}
\item{xaxt}{On/Off for xaxis text}
@@ -109,11 +137,21 @@
\item{medcol}{Boxplot - median line color}
\item{medlwd}{Boxplot - median line width}
+
+\item{frame.plot}{On/Off for surrounding box (\code{spec_line} only). Default
+is False.}
+
+\item{lwd}{Line width for \code{spec_line}; within \code{spec_line}, the \code{minmax}
+argument defaults to use this value for \code{cex} for points. Default is 2.}
+
+\item{minmax, min, max}{Arguments passed to \code{points} to highlight minimum
+and maximum values in \code{spec_line}. If \code{min} or \code{max} are \code{NULL}, they
+default to the value of \code{minmax}. Set to an empty \code{list()} to disable.}
}
\description{
These functions helps you quickly generate sets of sparkline
-style plots using base R plotting system. Currently, we support histogram
-and boxplot. You can use them together with \code{column_spec} to
+style plots using base R plotting system. Currently, we support histogram,
+boxplot, and line. You can use them together with \code{column_spec} to
generate inline plot in tables. By default, this function will save images
in a folder called "kableExtra" and return the address of the file.
}
diff --git a/vignettes/awesome_table_in_html.Rmd b/vignettes/awesome_table_in_html.Rmd
index ae75688..cb7b1e3 100644
--- a/vignettes/awesome_table_in_html.Rmd
+++ b/vignettes/awesome_table_in_html.Rmd
@@ -235,16 +235,17 @@
c("kableExtra_sm.png", "kableExtra_sm.png"), 50, 50))
```
-`kableExtra` also provides a few inline plotting tools. Right now, there are `spec_hist` and `spec_boxplot`. One key feature is that by default, the limits of every subplots are fixed so you can compare across rows. Note that in html, you can also use package `sparkline` to create some jquery based interactive sparklines. Check out the end of this guide for details.
+`kableExtra` also provides a few inline plotting tools. Right now, there are `spec_hist`, `spec_boxplot`, and `spec_line`. One key feature is that by default, the limits of every subplots are fixed so you can compare across rows. Note that in html, you can also use package `sparkline` to create some jquery based interactive sparklines. Check out the end of this guide for details.
```{r}
mpg_list <- split(mtcars$mpg, mtcars$cyl)
-inline_plot <- data.frame(cyl = c(4, 6, 8), mpg_box = "", mpg_hist = "")
+inline_plot <- data.frame(cyl = c(4, 6, 8), mpg_box = "", mpg_hist = "", mpg_line = "")
inline_plot %>%
kbl(booktabs = T) %>%
kable_paper(full_width = F) %>%
column_spec(2, image = spec_boxplot(mpg_list)) %>%
- column_spec(3, image = spec_hist(mpg_list))
+ column_spec(3, image = spec_hist(mpg_list)) %>%
+ column_spec(4, image = spec_line(mpg_list, same_lim = FALSE))
```
## Row spec
diff --git a/vignettes/awesome_table_in_pdf.Rmd b/vignettes/awesome_table_in_pdf.Rmd
index 4046d9e..2fd3b25 100644
--- a/vignettes/awesome_table_in_pdf.Rmd
+++ b/vignettes/awesome_table_in_pdf.Rmd
@@ -263,16 +263,17 @@
c("kableExtra_sm.png", "kableExtra_sm.png"), 50, 50))
```
-`kableExtra` also provides a few inline plotting tools. Right now, there are `spec_hist` and `spec_boxplot`. One key feature is that by default, the limits of every subplots are fixed so you can compare across rows.
+`kableExtra` also provides a few inline plotting tools. Right now, there are `spec_hist`, `spec_boxplot`, and `spec_line`. One key feature is that by default, the limits of every subplots are fixed so you can compare across rows.
```{r}
mpg_list <- split(mtcars$mpg, mtcars$cyl)
-inline_plot <- data.frame(cyl = c(4, 6, 8), mpg_box = "", mpg_hist = "")
+inline_plot <- data.frame(cyl = c(4, 6, 8), mpg_box = "", mpg_hist = "", mpg_line = "")
inline_plot %>%
kbl(booktabs = T) %>%
kable_paper(full_width = F) %>%
column_spec(2, image = spec_boxplot(mpg_list)) %>%
- column_spec(3, image = spec_hist(mpg_list))
+ column_spec(3, image = spec_hist(mpg_list)) %>%
+ column_spec(4, image = spec_line(mpg_list, same_lim = FALSE))
```
## Row spec