Skip to content

Commit

Permalink
export ramp_colours for use in other packages
Browse files Browse the repository at this point in the history
  • Loading branch information
mjskay committed Feb 24, 2024
1 parent 892ebe5 commit dab9d89
Show file tree
Hide file tree
Showing 40 changed files with 430 additions and 231 deletions.
5 changes: 3 additions & 2 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: ggdist
Title: Visualizations of Distributions and Uncertainty
Version: 3.3.1.9000
Date: 2023-11-26
Version: 3.3.2
Date: 2024-02-24
Authors@R: c(
person("Matthew", "Kay", role = c("aut", "cre"), email = "[email protected]"),
person("Brenton M.", "Wiernik", role = "ctb", email = "[email protected]")
Expand Down Expand Up @@ -97,6 +97,7 @@ Collate:
"guide_rampbar.R"
"lkjcorr_marginal.R"
"parse_dist.R"
"partial_colour_ramp.R"
"point_interval.R"
"position_dodgejust.R"
"pr.R"
Expand Down
2 changes: 2 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,7 @@ export(mode_qi)
export(mode_ul)
export(p_)
export(parse_dist)
export(partial_colour_ramp)
export(plkjcorr_marginal)
export(point_interval)
export(position_dodgejust)
Expand All @@ -179,6 +180,7 @@ export(qi)
export(qlkjcorr_marginal)
export(qstudent_t)
export(r_dist_name)
export(ramp_colours)
export(rlkjcorr_marginal)
export(rstudent_t)
export(scale_color_ramp_continuous)
Expand Down
29 changes: 15 additions & 14 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# ggdist (development version)
# ggdist 3.3.2

New features and enhancements:
Major changes:

* The `geom_slabinterval()` and `geom_dotsinterval()` families gain "sub-guides",
which can be passed to the `subguide` parameter to create axis annotations for
Expand All @@ -12,10 +12,16 @@ New features and enhancements:
for the upcoming weighted random variable type in the *posterior* package.
* Blurry dotplots are now supported using `geom_blur_dots()`, which accepts an
`sd` aesthetic to set the standard deviation of the blur on each dot.
Intervals can also be used in place of blur by passing `blur = "interval"`.
This geom is used by the new `stat_mcse_dots()` to show quantiles along with
their error using blur (#63).
* The new `breaks_quantiles()` histogram breaks function allows the construction
of quantile histograms with `density_histogram()`, `stat_histinterval()`, etc.

Minor changes:

* The default histogram bin selection algorithm is now `"Scott"` instead of
`"Sturges"`, as `"Sturges"` tends to be too conservative (#214).
* The `at` parameter to `stat_spike()` (or its names) now determines values of
an `at` computed variable, which can be mapped onto aesthetics via `after_stat()`
to more easily label spikes. (#203; thanks @mattansb for the suggestion).
Expand All @@ -25,6 +31,13 @@ New features and enhancements:
an explicit data type, `partial_colour_ramp()`, to encode color ramps and
their origin colors. This should make it easier to apply explicit color ramps
without using scale functions, if needed (#209).
* Several dependency reductions: removed {cowplot}, {purrr}, and {forcats}
from *Suggests*; moved {tidyselect} and {dplyr} from *Imports* to *Suggests*.
The latter two are only strictly necessary for `curve_interval()` due to its
use of grouped data frames and tidy selection to specify which columns are
conditional and which are joint (the use of grouped data frames with
`point_interval()` is less strictly necessary, and not used by stats, so
is easier to avoid as an absolute dependency).

Documentation:

Expand All @@ -36,18 +49,6 @@ Bug fixes:
* Ensure `Mode()` works on analytical constant distributions.
* Various fixes to ensure compatibility with {ggplot2} 3.5.0.

Minor changes:

* The default histogram bin selection algorithm is now `"Scott"` instead of
`"Sturges"`, as `"Sturges"` tends to be too conservative (#214).
* Several dependency reductions: removed {cowplot}, {purrr}, and {forcats}
from *Suggests*; moved {tidyselect} and {dplyr} from *Imports* to *Suggests*.
The latter two are only strictly necessary for `curve_interval()` due to its
use of grouped data frames and tidy selection to specify which columns are
conditional and which are joint (the use of grouped data frames with
`point_interval()` is less strictly necessary, and not used by stats, so
is easier to avoid as an absolute dependency).


# ggdist 3.3.1

Expand Down
4 changes: 2 additions & 2 deletions R/geom_dotsinterval.R
Original file line number Diff line number Diff line change
Expand Up @@ -638,9 +638,9 @@ GeomDots = ggproto("GeomDots", GeomDotsinterval,
override_slab_aesthetics = function(self, s_data) {
# we define these differently from geom_dotsinterval to make this easier to use on its own
s_data$colour = s_data[["slab_colour"]] %||% s_data[["colour"]]
s_data$colour = apply_colour_ramp(s_data[["colour"]], s_data[["colour_ramp"]])
s_data$colour = ramp_colours(s_data[["colour"]], s_data[["colour_ramp"]])
s_data$fill = s_data[["slab_fill"]] %||% s_data[["fill"]]
s_data$fill = apply_colour_ramp(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$fill = ramp_colours(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$alpha = s_data[["slab_alpha"]] %||% s_data[["alpha"]]
s_data$linewidth = s_data[["slab_linewidth"]] %||% s_data[["slab_size"]] %||%
s_data[["linewidth"]] %||% s_data[["size"]]
Expand Down
4 changes: 2 additions & 2 deletions R/geom_lineribbon.R
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ draw_key_lineribbon = function(self, data, params, size) {
if (is.null(data[["fill"]]) && (!is.null(data[["fill_ramp"]]) || !all(is.na(data[["alpha"]])))) {
data$fill = self$default_key_aes$fill
}
data$fill = apply_colour_ramp(data$fill, data$fill_ramp)
data$fill = ramp_colours(data$fill, data$fill_ramp)

if (!is.null(data[["colour"]]) || !is.null(data[["linewidth"]])) {
data$colour = data[["colour"]] %||% self$default_key_aes$colour
Expand Down Expand Up @@ -201,7 +201,7 @@ GeomLineribbon = ggproto("GeomLineribbon", AbstractGeom,
# colors ramp to the same fill (e.g. both ramp to 100% white) they will get
# grouped together erroneously
data$fill_raw = data$fill
data$fill = apply_colour_ramp(data$fill, data$fill_ramp)
data$fill = ramp_colours(data$fill, data$fill_ramp)

# ribbons do not autogroup by color/fill/linetype, so if someone groups by changing the color
# of the line or by setting fill, the ribbons might give an error. So we will do the
Expand Down
4 changes: 2 additions & 2 deletions R/geom_slab.R
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,9 @@ GeomSlab = ggproto("GeomSlab", GeomSlabinterval,
override_slab_aesthetics = function(self, s_data) {
# we define these differently from geom_slabinterval to make this easier to use on its own
s_data$colour = s_data[["slab_colour"]] %||% s_data[["colour"]]
s_data$colour = apply_colour_ramp(s_data[["colour"]], s_data[["colour_ramp"]])
s_data$colour = ramp_colours(s_data[["colour"]], s_data[["colour_ramp"]])
s_data$fill = s_data[["slab_fill"]] %||% s_data[["fill"]]
s_data$fill = apply_colour_ramp(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$fill = ramp_colours(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$alpha = s_data[["slab_alpha"]] %||% s_data[["alpha"]]
s_data$linewidth =
s_data[["slab_linewidth"]] %||% s_data[["slab_size"]] %||%
Expand Down
8 changes: 4 additions & 4 deletions R/geom_slabinterval.R
Original file line number Diff line number Diff line change
Expand Up @@ -334,7 +334,7 @@ draw_path = function(data, panel_params, coord) {
override_slab_aesthetics = function(self, s_data) {
s_data$colour = s_data[["slab_colour"]]
s_data$fill = s_data[["slab_fill"]] %||% s_data[["fill"]]
s_data$fill = apply_colour_ramp(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$fill = ramp_colours(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$alpha = s_data[["slab_alpha"]] %||% s_data[["alpha"]]
#TODO: insert slab_size deprecation warning?
s_data$linewidth = s_data[["slab_linewidth"]] %||% s_data[["slab_size"]]
Expand All @@ -344,7 +344,7 @@ override_slab_aesthetics = function(self, s_data) {

override_point_aesthetics = function(self, p_data, size_domain, size_range, fatten_point) {
p_data$colour = p_data[["point_colour"]] %||% p_data[["colour"]]
p_data$colour = apply_colour_ramp(p_data[["colour"]], p_data[["colour_ramp"]])
p_data$colour = ramp_colours(p_data[["colour"]], p_data[["colour_ramp"]])
p_data$fill = p_data[["point_fill"]] %||% p_data[["fill"]]
p_data$alpha = p_data[["point_alpha"]] %||% p_data[["alpha"]]
# TODO: insert fatten_point deprecation warning
Expand All @@ -355,7 +355,7 @@ override_point_aesthetics = function(self, p_data, size_domain, size_range, fatt

override_interval_aesthetics = function(self, i_data, size_domain, size_range) {
i_data$colour = i_data[["interval_colour"]] %||% i_data[["colour"]]
i_data$colour = apply_colour_ramp(i_data[["colour"]], i_data[["colour_ramp"]])
i_data$colour = ramp_colours(i_data[["colour"]], i_data[["colour_ramp"]])
i_data$alpha = i_data[["interval_alpha"]] %||% i_data[["alpha"]]
# TODO: insert interval_size deprecation warning
i_data$linewidth = transform_size(
Expand Down Expand Up @@ -695,7 +695,7 @@ GeomSlabinterval = ggproto("GeomSlabinterval", AbstractGeom,
argument, as it may result in strange scaling of legends; this argument is a holdover from earlier versions
that did not have size aesthetics targeting the point and interval separately. If you want to adjust the
size of the interval or points separately, you can also use the `linewidth` or `point_size`
aesthetics; see [scales].
aesthetics; see [sub-geometry-scales].
'),
fatten_point = glue_doc('
A multiplicative factor used to adjust the size of the point relative to the size of the
Expand Down
4 changes: 2 additions & 2 deletions R/geom_spike.R
Original file line number Diff line number Diff line change
Expand Up @@ -154,8 +154,8 @@ GeomSpike = ggproto("GeomSpike", GeomSlab,
), GeomSlab$hidden_aes),

override_slab_aesthetics = function(self, s_data) {
s_data$colour = apply_colour_ramp(s_data[["colour"]], s_data[["colour_ramp"]])
s_data$fill = apply_colour_ramp(s_data[["fill"]], s_data[["fill_ramp"]])
s_data$colour = ramp_colours(s_data[["colour"]], s_data[["colour_ramp"]])
s_data$fill = ramp_colours(s_data[["fill"]], s_data[["fill_ramp"]])
s_data
},

Expand Down
4 changes: 2 additions & 2 deletions R/guide_rampbar.R
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@
#' @return
#' A guide object.
#' @author Matthew Kay
#' @seealso [scale_fill_ramp_continuous()], [scale_colour_ramp_continuous()].
#' @family colour ramp functions
#' @examples
#'
#' library(dplyr)
Expand Down Expand Up @@ -79,7 +79,7 @@ guide_rampbar = function(..., to = "gray65", available_aes = c("fill_ramp", "col
if (reverse) {
bar = bar[rev(seq_len(nrow(bar))), , drop = FALSE]
}
bar$colour = alpha(apply_colour_ramp(to, bar$colour), alpha)
bar$colour = alpha(ramp_colours(to, bar$colour), alpha)
bar
}
)
Expand Down
152 changes: 152 additions & 0 deletions R/partial_colour_ramp.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
# partial_colour_ramp datatype used by scale_colour_ramp
#
# Author: mjskay
###############################################################################


# partial_colour_ramp -------------------------------------------------------

#' Partial colour ramp (datatype)
#'
#' A representation of a partial ramp between two colours: the origin colour
#' (`from`) and the distance from the origin colour to the target colour
#' (`amount`, a value between `0` and `1`). The target colour of the ramp
#' can be filled in later using `ramp_colours()`, producing a colour.
#'
#' @param amount Numeric vector between `0` and `1` giving amounts to ramp
#' the colour. `0` corresponds to the colour `from`.
#' @param from Character vector giving colours to ramp from.
#'
#' @details
#' This datatype is used by [scale_colour_ramp] to create ramped colours in
#' \pkg{ggdist} geoms. It is a [vctrs::rcrd] datatype with two fields:
#' `"amount"`, the amount to ramp, and `"from"`, the colour to ramp from.
#'
#' Colour ramps can be applied (i.e. translated into colours) using
#' [ramp_colours()], which can be used with [partial_colour_ramp()]
#' to implement geoms that make use of `colour_ramp` or `fill_ramp` scales.
#' @return
#' A [vctrs::rcrd] of class `"ggdist_partial_colour_ramp"` with fields
#' `"amount"` and `"from"`.
#' @author Matthew Kay
#' @family colour ramp functions
#' @examples
#' pcr = partial_colour_ramp(c(0, 0.25, 0.75, 1), "red")
#' pcr
#'
#' ramp_colours("blue", pcr)
#' @name partial_colour_ramp
NULL


# partial_colour_ramp datatype --------------------------------------------

new_partial_colour_ramp = function(amount = double(), from = "white") {
if (length(amount) < 1) x = double()
stopifnot(is.double(amount))
if (length(from) <= 1) from = rep(from, length(amount))
stopifnot(is.character(from))
vctrs::new_rcrd(list(amount = amount, from = from), class = "ggdist_partial_colour_ramp")
}

#' @rdname partial_colour_ramp
#' @export
partial_colour_ramp = function(amount = double(), from = "white") {
amount = vctrs::vec_cast(amount, numeric())
from = vctrs::vec_cast(from, character())
new_partial_colour_ramp(amount, from)
}


# formatting --------------------------------------------------------------

#' @export
vec_ptype_full.ggdist_partial_colour_ramp = function(x, ...) "partial_colour_ramp"
#' @export
vec_ptype_abbr.ggdist_partial_colour_ramp = function(x, ...) "rmp"

#' @export
format.ggdist_partial_colour_ramp = function(x, ...) {
sprintf("[%s from %s]", field(x, "amount"), field(x, "from"))
}


# predicates --------------------------------------------------------------

#' @export
is.na.ggdist_partial_colour_ramp = function(x) {
is.na(field(x, "amount")) | is.na(field(x, "from"))
}


# casting -------------------------------------------------------

as_partial_colour_ramp = function(x) {
vec_cast(x, new_partial_colour_ramp())
}

#' @export
vec_ptype2.ggdist_partial_colour_ramp.ggdist_partial_colour_ramp = function(x, y, ...) new_partial_colour_ramp()

#' @export
vec_ptype2.ggdist_partial_colour_ramp.double = function(x, y, ...) new_partial_colour_ramp()
#' @export
vec_ptype2.double.ggdist_partial_colour_ramp = function(x, y, ...) new_partial_colour_ramp()
#' @export
vec_ptype2.ggdist_partial_colour_ramp.integer = function(x, y, ...) new_partial_colour_ramp()
#' @export
vec_ptype2.integer.ggdist_partial_colour_ramp = function(x, y, ...) new_partial_colour_ramp()

#' @export
vec_cast.ggdist_partial_colour_ramp.double = function(x, to, ...) partial_colour_ramp(x)
#' @export
vec_cast.ggdist_partial_colour_ramp.integer = function(x, to, ...) partial_colour_ramp(x)
#' @export
vec_cast.double.ggdist_partial_colour_ramp = function(x, to, ...) field(x, "amount")
#' @export
vec_cast.integer.ggdist_partial_colour_ramp = function(x, to, ...) as.integer(field(x, "amount"))


# applying colour ramps --------------------------------------------------------

#' Apply partial colour ramps
#'
#' Given vectors of colours and [`partial_colour_ramp`]s, ramps the colours
#' according to the parameters of the partial colour ramps, returning
#' a vector of the same length as the inputs giving the transformed
#' (ramped) colours.
#'
#' @param colour character vector of colours.
#' @param ramp a [`partial_colour_ramp`] vector.
#' @details
#' Takes vectors of colours and [`partial_colour_ramp`]s and produces
#' colours by interpolating between each `from` colour and the target `colour`
#' the specified `amount` (where `amount` and `from` are the corresponding
#' fields of the `ramp`).
#'
#' For example, to add support for the `fill_ramp` aesthetic to a geometry,
#' this line could be used inside the `draw_group()` or `draw_panel()` method
#' of a geom:
#'
#' ```
#' data$fill = ramp_colours(data$fill, data$fill_ramp)
#' ```
#' @return
#' A character vector of colours.
#' @author Matthew Kay
#' @family colour ramp functions
#' @examples
#' pcr = partial_colour_ramp(c(0, 0.25, 0.75, 1), "red")
#' pcr
#'
#' ramp_colours("blue", pcr)
#' @export
ramp_colours = function(colour, ramp) {
if (is.null(colour) || is.null(ramp)) return(colour)
ramp = vec_cast(ramp, new_partial_colour_ramp())
c(colour, ramp) %<-% vec_recycle_common(colour, ramp)

map2_chr_(colour, ramp, function(colour_i, ramp_i) {
scales::seq_gradient_pal(field(ramp_i, "from"), colour_i)(field(ramp_i, "amount"))
})
}
Loading

0 comments on commit dab9d89

Please sign in to comment.