Nothing
#' Add a scale to a ggvis plot
#'
#' This creates a scale object for a given scale and variable type, and adds it
#' to a ggvis plot. The scale object is populated with default settings, which
#' depend on the scale (e.g. fill, x, opacity) and the type of variable (e.g.
#' numeric, nominal, ordinal). Any settings that are passed in as arguments
#' will override the defaults.
#'
#' @section Scale selection:
#'
#' ggvis supports the following types of scales. Typical uses for each scale
#' type are listed below:
#' \itemize{
#' \item numeric For continuous numeric values.
#' \item nominal For character vectors and factors.
#' \item ordinal For ordered factors (these presently behave the same as
#' nominal).
#' \item logical For logical (TRUE/FALSE) values.
#' \item datetime For dates and date-times.
#' }
#'
#' Each type has a corresponding function: \code{scale_numeric},
#' \code{scale_nominal}, and so on.
#'
#' The scale types for ggvis are mapped to scale types for Vega, which include
#' "ordinal", "quantitative", and "time". See \code{\link{ggvis_scale}} for more
#' details.
#'
#' Given a scale and type, the range is selected based on the combination of the
#' \code{scale} and \code{type}. For example, you get a different range of
#' colours depending on whether the data is numeric, ordinal, or nominal. Some
#' scales also set other properties. For example, nominal/ordinal position
#' scales also add some padding so that points are spaced away from plot edges.
#'
#' Not all combinations have an existing default scale. If you use a
#' combination that does not have an existing combination, it may suggest
#' you're displaying the data in a suboptimal way. For example, there is
#' no default for a numeric shape scale, because there's no obvious way to
#' map continuous values to discrete shapes.
#'
#' @param vis A ggvis object.
#' @param scale The name of a scale, such as "x", "y", "fill", "stroke", etc.
#' @param type A variable type. One of "numeric", "nominal", "ordinal",
#' "logical", "datetime".
#' @param ... other arguments passed to the scale function. See the help for
#' \code{\link{scale_numeric}}, \code{\link{scale_ordinal}} and
#' \code{\link{scale_datetime}} for more details. For example, you might
#' supply \code{trans = "log"} to create a log scale.
#' @param name If \code{NULL}, the default, the scale name is the same as
#' \code{scale}. Set this to a custom name to create multiple scales for
#' stroke or fill, or (god forbid) a secondary y scale.
#' @examples
#' p <- mtcars %>%
#' ggvis(x = ~wt, y = ~mpg, fill = ~factor(cyl), stroke = ~hp) %>%
#' layer_points()
#'
#' p %>% scale_numeric("x")
#' p %>% scale_numeric("stroke")
#' p %>% scale_nominal("fill")
#'
#' # You can also supply additional arguments or override the defaults
#' p %>% scale_numeric("x", trans = "log")
#' p %>% scale_numeric("stroke", range = c("red", "blue"))
#' @name scales
#' @aliases set_default_scale set_dscale
NULL
#' Add a numeric scale to a ggvis object.
#'
#' A numeric (quantitative) scale controls the mapping of continuous variables
#' to visual properties.
#'
#' The default values for most of the arguments is NULL. When the plot is
#' created, these NULL values will be replaced with default values, as indicated
#' below.
#'
#' @param vis A ggvis object.
#' @param property The name of a visual property, such as "x", "y", "fill",
#' "stroke". Note both x and x2 use the "x" scale (similarly for y and y2).
#' fillOpacity, opacity and strokeOpacity use the "opacity" scale.
#' @inheritParams ggvis_scale
#' @param trans A scale transformation: one of "linear", "log", "pow", "sqrt",
#' "quantile", "quantize", "threshold". Default is "linear".
#' @param exponent Sets the exponent of the scale transformation. For pow
#' transform only.
#' @param clamp If \code{TRUE}, values that exceed the data domain are clamped
#' to either the minimum or maximum range value. Default is \code{FALSE}.
#' @param nice If \code{TRUE}, modifies the scale domain to use a more
#' human-friendly number range (e.g., 7 instead of 6.96). Default is
#' \code{FALSE}.
#' @param zero If \code{TRUE}, ensures that a zero baseline value is included
#' in the scale domain. This option is ignored for non-quantitative scales.
#' Default is \code{FALSE}.
#' @param expand A multiplier for how much the scale should be expanded beyond
#' the domain of the data. For example, if the data goes from 10 to 110, and
#' \code{expand} is 0.05, then the resulting domain of the scale is 5 to 115.
#' Set to 0 and use \code{nice=FALSE} if you want exact control over the
#' domain. If left \code{NULL}, behavior will depend on the scale type. For
#' positional scales (x and y), \code{expand} will default to 0.05. For other
#' scales, it will default to 0.
#' @seealso \code{\link{scales}}, \code{\link{scale_ordinal}},
#' \url{https://vega.github.io/vega/docs/scales/#quantitative}
#' @family scales
#' @export
#' @examples
#' p <- mtcars %>% ggvis(~wt, ~mpg, fill = ~hp) %>% layer_points()
#'
#' p %>% scale_numeric("y")
#'
#' p %>% scale_numeric("y", trans = "pow", exponent = 0.5)
#'
#' p %>% scale_numeric("y", trans = "log")
#'
#' # Can control other properties other than x and y
#' p %>% scale_numeric("fill", domain = c(0, 120), clamp = TRUE)
#'
#' # Set range of data from 0 to 3
#' p %>% scale_numeric("x", domain = c(0, 3), clamp = TRUE, expand = 0,
#' nice = FALSE)
#'
#' # Lower bound is set to lower limit of data, upper bound set to 3.
#' p %>% scale_numeric("x", domain = c(NA, 3), clamp = TRUE, nice = FALSE)
scale_numeric <- function(vis, property, domain = NULL, range = NULL,
reverse = NULL, round = NULL,
trans = NULL, clamp = NULL, exponent = NULL,
nice = NULL, zero = NULL, expand = NULL,
name = property, label = NULL, override = NULL) {
assert_that(is.null(trans) || trans %in% c("linear", "log", "pow", "sqrt",
"quantile", "quantize", "threshold"))
if (!is.null(exponent) && !identical(trans, "pow")) {
stop("May only set exponent when pow = 'trans'")
}
assert_that(is.null(exponent) || (is.numeric(exponent) && length(exponent) == 1))
assert_that(is.null(reverse) || is.flag(reverse))
assert_that(is.null(round) || is.flag(round))
assert_that(is.null(clamp) || is.flag(clamp))
assert_that(is.null(nice) || is.flag(nice))
assert_that(is.null(zero) || is.flag(zero))
assert_that(is.null(expand) || (is.numeric(expand) && length(expand) <= 2))
vscale <- ggvis_scale(
property = property,
name = name,
label = label,
type = trans,
subclass = "numeric",
exponent = exponent,
clamp = clamp,
nice = nice,
zero = zero,
domain = domain,
range = range,
reverse = reverse,
round = round,
expand = expand,
override = override
)
add_scale(vis, vscale)
}
#' Add a date-time scale to a ggvis object.
#'
#' A date/time scale controls the mapping of date and time variables to
#' visual properties.
#'
#' @param vis A ggvis object.
#' @param property The name of a property, such as "x", "y", "fill", "stroke", etc.
#' @inheritParams ggvis_scale
#' @param clamp If \code{TRUE}, values that exceed the data domain are clamped
#' to either the minimum or maximum range value. Default is \code{FALSE}.
#' @param nice If specified, modifies the scale domain to use a more
#' human-friendly value range. Should be a string indicating the desired time
#' interval; legal values are "second", "minute", "hour", "day", "week",
#' "month", or "year".
#' @param expand A multiplier for how much the scale should be expanded beyond
#' the domain of the data. For example, if the data goes from 10 to 110, and
#' \code{expand} is 0.05, then the resulting domain of the scale is 5 to 115.
#' Set to 0 and use \code{nice=FALSE} if you want exact control over the
#' domain.
#' @param utc if \code{TRUE}, uses UTC times. Default is \code{FALSE}.
#' @seealso \code{\link{scales}}, \code{\link{scale_numeric}},
#' \url{https://vega.github.io/vega/docs/scales/#time}
#' @family scales
#' @export
#' @examples
#' set.seed(2934)
#' dat <- data.frame(
#' time = as.Date("2013-07-01") + 1:100,
#' value = seq(1, 10, length.out = 100) + rnorm(100)
#' )
#' p <- dat %>% ggvis(~time, ~value) %>% layer_points()
#'
#' # Start and end on month boundaries
#' p %>% scale_datetime("x", nice = "month")
#'
#'
#' dist <- data.frame(times = as.POSIXct("2013-07-01", tz = "GMT") +
#' rnorm(200) * 60 * 60 * 24 * 7)
#' p <- dist %>% ggvis(x = ~times) %>% layer_histograms()
#' p
#'
#' # Start and end on month boundaries
#' p %>% scale_datetime("x", nice = "month")
#'
#' p %>% scale_datetime("x", utc = TRUE)
scale_datetime <- function(vis, property, domain = NULL, range = NULL,
reverse = NULL, round = NULL, utc = NULL,
clamp = NULL, nice = NULL, expand = NULL,
name = property, label = NULL, override = NULL) {
assert_that(is.null(reverse) || is.flag(reverse))
assert_that(is.null(round) || is.flag(round))
assert_that(is.null(utc) || is.flag(utc))
assert_that(is.null(clamp) || is.flag(clamp))
assert_that(is.null(nice) || nice %in% c("second", "minute", "hour", "day",
"week", "month", "year"))
assert_that(is.null(expand) || (is.numeric(expand) && length(expand) <= 2))
if (!is.null(utc)) {
utc <- if (isTRUE(utc)) "utc" else "time"
}
vscale <- ggvis_scale(
property = property,
name = name,
label = label,
type = utc,
subclass = "datetime",
clamp = clamp,
nice = nice,
domain = domain,
range = range,
reverse = reverse,
round = round,
expand = expand,
override = override
)
add_scale(vis, vscale)
}
#' Add a ordinal, nominal, or logical scale to a ggvis object.
#'
#' Ordinal, nominal, and logical scales are all categorical, and are treated
#' similarly by ggvis.
#'
#' @param vis A ggvis object.
#' @param property The name of a property, such as "x", "y", "fill", "stroke", etc.
#' @inheritParams ggvis_scale
#' @param points If \code{TRUE} (default), distributes the ordinal values over a
#' quantitative range at uniformly spaced points. The spacing of the points
#' can be adjusted using the padding property. If \code{FALSE}, the ordinal
#' scale will construct evenly-spaced bands, rather than points. Note that
#' if any mark is added with a \code{\link{band}()} prop, then the scale for
#' that prop will automatically have \code{points} set to \code{FALSE}.
#' @param padding Applies spacing among ordinal elements in the scale range.
#' The actual effect depends on how the scale is configured. If the points
#' parameter is true, the padding value is interpreted as a multiple of the
#' spacing between points. A reasonable value is 1.0, such that the first and
#' last point will be offset from the minimum and maximum value by half the
#' distance between points. Otherwise, padding is typically in the range
#' [0, 1] and corresponds to the fraction of space in the range interval to
#' allocate to padding. A value of 0.5 means that the range band width will
#' be equal to the padding width. For positional (x and y) scales, the default
#' padding is 0.1. For other scales, the default padding is 0.5.
#' @param sort If \code{TRUE}, the values in the scale domain will be sorted
#' according to their natural order. Default is \code{FALSE}.
#' @seealso \code{\link{scales}}, \code{\link{scale_numeric}},
#' \url{https://vega.github.io/vega/docs/scales/#ordinal}.
#' @family scales
#' @export
#' @examples
#' p <- PlantGrowth %>% ggvis(~group, ~weight) %>% layer_points()
#'
#' p
#' p %>% scale_nominal("x", padding = 0)
#' p %>% scale_nominal("x", padding = 1)
#'
#' p %>% scale_nominal("x", reverse = TRUE)
#'
#' p <- ToothGrowth %>% group_by(supp) %>%
#' ggvis(~len, fill = ~supp) %>%
#' layer_histograms(width = 4, stack = TRUE)
#'
#' # Control range of fill scale
#' p %>% scale_nominal("fill", range = c("pink", "lightblue"))
#'
#' # There's no default range when the data is categorical but the output range
#' # is continuous, as in the case of opacity. In these cases, you can
#' # manually specify the range for the scale.
#' mtcars %>% ggvis(x = ~wt, y = ~mpg, opacity = ~factor(cyl)) %>%
#' layer_points() %>%
#' scale_nominal("opacity", range = c(0.2, 1))
scale_ordinal <- function(vis, property, domain = NULL, range = NULL,
reverse = NULL, round = NULL,
points = NULL, padding = NULL, sort = NULL,
name = property, label = NULL, override = NULL) {
assert_that(is.null(reverse) || is.flag(reverse))
assert_that(is.null(round) || is.flag(round))
assert_that(is.null(points) || is.flag(points))
assert_that(is.null(padding) || (is.numeric(padding) && length(padding) == 1))
assert_that(is.null(sort) || is.flag(sort))
vscale <- ggvis_scale(
property = property,
name = name,
label = label,
type = "ordinal",
points = points,
padding = padding,
sort = sort,
subclass = "ordinal",
domain = domain,
range = range,
reverse = reverse,
round = round,
override = override
)
add_scale(vis, vscale)
}
#' @rdname scale_ordinal
#' @export
scale_nominal <- function(vis, property, domain = NULL, range = NULL,
reverse = NULL, round = NULL,
points = NULL, padding = NULL, sort = NULL,
name = property, label = NULL, override = NULL) {
assert_that(is.null(reverse) || is.flag(reverse))
assert_that(is.null(round) || is.flag(round))
assert_that(is.null(points) || is.flag(points))
assert_that(is.null(padding) || (is.numeric(padding) && length(padding) == 1))
assert_that(is.null(sort) || is.flag(sort))
vscale <- ggvis_scale(
property = property,
name = name,
label = label,
type = "ordinal",
points = points,
padding = padding,
sort = sort,
subclass = "nominal",
domain = domain,
range = range,
reverse = reverse,
round = round,
override = override
)
add_scale(vis, vscale)
}
#' @rdname scale_ordinal
#' @export
scale_logical <- scale_nominal
#' Add x_rel and y_rel scales
#'
#' This function adds scales named \code{x_rel} and \code{y_rel}, each of which
#' has a domain of 0 to 1, and the range is the plot's width or height.
#' These scales are useful for positioning visual elements relative to the
#' plotting area. For example, with legends.
#'
#' @seealso \code{\link{add_legend}} for a usage example.
#'
#' @param vis A ggvis object.
#' @export
add_relative_scales <- function(vis) {
vis <- scale_numeric(vis, "x", name = "x_rel", domain = c(0, 1),
range = "width", expand = 0)
vis <- scale_numeric(vis, "y", name = "y_rel", domain = c(0, 1),
range = "height", expand = 0)
vis
}
scale_auto <- function(vis, scale, ..., quiet = FALSE) {
info <- vis$scales[[scale]]
if (!quiet) {
message("Adding scale_", info$type, "(\"", scale, "\")")
}
scale_fun <- match.fun(paste0("scale_", info$type))
vis <- scale_fun(vis, scale, ...)
}
#' Set the label for a scale
#' @param vis A ggvis object.
#' @param scale The name of a scale, like "x".
#' @param label Text to use for the label.
set_scale_label <- function(vis, scale, label) {
add_scale(vis, ggvis_scale(scale, label = label))
}
# Is this scale object countable?
scale_countable <- function(scale) UseMethod("scale_countable")
#' @export
scale_countable.scale_numeric <- function(scale) FALSE
#' @export
scale_countable.scale_datetime <- function(scale) FALSE
#' @export
scale_countable.scale_nominal <- function(scale) TRUE
#' @export
scale_countable.scale_ordinal <- function(scale) TRUE
#' @export
scale_countable.scale_logical <- function(scale) TRUE
#' @export
scale_countable.default <- function(scale) NULL
# Make sure that scales are well-formed for a vega spec
check_scales_complete <- function(vis) {
check_scale_complete <- function(scale) {
if (is.null(scale$range)) {
warning(paste(
sprintf("Scale '%s' for property '%s' is missing a range.", scale$name, scale$property),
"ggvis tries to automatically provide ranges for scales, but it doesn't know how in this case.",
"You must specify the range manually.",
"See ?scale_nominal or ?scale_numeric for more information and examples."
), call. = FALSE)
}
}
lapply(vis$scales, check_scale_complete)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.