#' Error plot for `euler` objects
#'
#' This is a diagnostic tool for evaluating the fit from a call
#' to [euler()] visually. A color key is provided by default, which
#' represents the chosen error metric so that one can easily detect
#' which areas in the diagram to be skeptical about.
#'
#' Notice that this function is purely provided for diagnostic reasons
#' and does not come with the same kind of customization that
#' [plot.euler()] provides: the color legend can only be customized
#' in regards to its color palette and another key (instead of labels)
#' is completely turned off.
#'
#' @param x an object of class `euler`, typically the result of
#' a call to [euler()].
#' @param type error metric. `'regionError'` is the difference in
#' *percentage points* from the input
#' @param quantities whether to draw the error metric on the plot
#' @param pal color palette for the fills in the legend
#' @param ... arguments passed down to [plot.euler()]. Currently,
#' providing `fills`, `legend`, or `strips` are not allowed and
#' will return a warning.
#'
#' @return Returns an object of class `eulergram`, which will be
#' plotted on the device in the same manner as objects from
#' [plot.euler()]. See [plot.eulergram()] for details.
#'
#' @export
#'
#' @seealso [plot.euler()], [euler()],
#' [plot.eulergram()]
#'
#' @examples
#' error_plot(euler(organisms), quantities = FALSE)
error_plot <- function(x,
type = c("regionError", "residuals"),
quantities = TRUE,
pal = NULL,
...)
{
type <- match.arg(type)
dots <- list(...)
n <- 101 # number of colors in legend
if (!is.null(dots$fills))
stop("values for 'fills' are not allowed here and will be ignored.")
if (!is.null(dots$legend))
stop("values for 'legend' are not allowed here and will be ignored.")
if (!is.null(dots$strips))
stop("values for 'strips' are not allowed here and will be ignored.")
r <- switch(type,
residuals = stats::residuals(x),
regionError = sign(stats::residuals(x))*x$regionError)
if (is.null(pal)) {
pal <- grDevices::colorRampPalette(c("#67001F", "#B2182B", "#D6604D",
"#F4A582", "#FDDBC7", "#F7F7F7",
"#D1E5F0", "#92C5DE", "#4393C3",
"#2166AC", "#053061"),
space = "rgb")
}
lim <- max(c(abs(r), ifelse(type == "regionError", 0.01, 0)))
rng <- grDevices::extendrange(c(-lim, lim))
labels <- grid::grid.pretty(rng)
n_labels <- length(labels)
s <- seq(rng[1], rng[2], length.out = n)
ind <- findInterval(r, s)
labels_grob <- grid::textGrob(label = labels,
x = rep(0, length(labels)),
y = labels,
just = "left",
vp = grid::viewport(yscale = rng),
default.units = "native",
name = paste("eulerr", "error_plot", sep = "."))
heights <- grid::unit(c(1, 1, 1), c("lines", "null", "lines"))
widths <- grid::unit(c(1, 1, 1),
c("lines", "lines", "grobwidth"),
data = list(NULL, NULL, labels_grob))
layout <- grid::grid.layout(nrow = 3, ncol = 3,
heights = heights,
widths = widths,
respect = TRUE)
frame <- grid::frameGrob(
layout = layout,
vp = NULL,
name = paste("eulerr", "error_plot", "key", sep = ".")
)
step <- diff(range(s))/(n - 1)
y_rect <- seq(min(s) + step/2, max(s) - step/2, length.out = n - 1)
ticks_grob <- grid::segmentsGrob(
x0 = rep(0, n_labels),
y0 = labels,
x1 = rep(0.7, n_labels),
y1 = labels,
default.units = "native",
name = paste("eulerr", "error_plot", "key", "ticks", sep = "."),
vp = grid::viewport(yscale = rng)
)
box_grob <- grid::rectGrob(
vp = grid::viewport(yscale = rng),
height = diff(rng),
default.units = "native",
name = paste("eulerr", "error_plot", "key", "box", sep = "."),
gp = grid::gpar(fill = "transparent")
)
rect_grob <- grid::rectGrob(
x = rep(0.5, length(y_rect)),
y = y_rect,
default.units = "native",
height = step,
vp = grid::viewport(yscale = rng),
name = paste("eulerr", "error_plot", "key", "rect", sep = "."),
gp = grid::gpar(fill = pal(n), col = "transparent")
)
frame <- grid::placeGrob(frame, rect_grob, row = 2, col = 1)
frame <- grid::placeGrob(frame, box_grob, row = 2, col = 1)
frame <- grid::placeGrob(frame, ticks_grob, row = 2, col = 2)
frame <- grid::placeGrob(frame, labels_grob, row = 2, col = 3)
graphics::plot(x,
fills = pal(n)[ind],
labels = TRUE,
quantities = if (quantities) round(r, 3) else FALSE,
legend = frame,
...)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.