Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Scale palettes from theme #5946

Open
wants to merge 20 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion R/geom-text.R
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,7 @@
#' # Add aesthetic mappings
#' p + geom_text(aes(colour = factor(cyl)))
#' p + geom_text(aes(colour = factor(cyl))) +
#' scale_colour_discrete(l = 40)
#' scale_colour_hue(l = 40)
#' p + geom_label(aes(fill = factor(cyl)), colour = "white", fontface = "bold")
#'
#' # Scale size of text, and change legend key glyph from a to point
Expand Down
1 change: 1 addition & 0 deletions R/plot-build.R
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,7 @@ ggplot_build.ggplot <- function(plot) {
# Train and map non-position scales and guides
npscales <- scales$non_position_scales()
if (npscales$n() > 0) {
npscales$set_palettes(plot$theme)
lapply(data, npscales$train_df)
plot$guides <- plot$guides$build(npscales, plot$layers, plot$labels, data, plot$theme)
data <- lapply(data, npscales$map_df)
Expand Down
1 change: 1 addition & 0 deletions R/scale-.R
Original file line number Diff line number Diff line change
Expand Up @@ -526,6 +526,7 @@ Scale <- ggproto("Scale", NULL,
if (empty(df)) {
return()
}
self$palette <- self$palette %||% fallback_palette(self)

aesthetics <- intersect(self$aesthetics, names(df))
names(aesthetics) <- aesthetics
Expand Down
35 changes: 19 additions & 16 deletions R/scale-alpha.R
Original file line number Diff line number Diff line change
Expand Up @@ -31,8 +31,9 @@
#'
#' # Changing the title
#' p + scale_alpha("cylinders")
scale_alpha <- function(name = waiver(), ..., range = c(0.1, 1)) {
continuous_scale("alpha", name = name, palette = pal_rescale(range), ...)
scale_alpha <- function(name = waiver(), ..., range = NULL) {
palette <- if (!is.null(range)) pal_rescale(range) else NULL
continuous_scale("alpha", name = name, palette = palette, ...)
}

#' @rdname scale_alpha
Expand All @@ -41,8 +42,9 @@

#' @rdname scale_alpha
#' @export
scale_alpha_binned <- function(name = waiver(), ..., range = c(0.1, 1)) {
binned_scale("alpha", name = name, palette = pal_rescale(range), ...)
scale_alpha_binned <- function(name = waiver(), ..., range = NULL) {
palette <- if (!is.null(range)) pal_rescale(range) else NULL
binned_scale("alpha", name = name, palette = palette, ...)
}

#' @rdname scale_alpha
Expand All @@ -56,32 +58,33 @@

#' @rdname scale_alpha
#' @export
scale_alpha_ordinal <- function(name = waiver(), ..., range = c(0.1, 1)) {
discrete_scale(
"alpha", name = name,
palette = function(n) seq(range[1], range[2], length.out = n),
...
)
scale_alpha_ordinal <- function(name = waiver(), ..., range = NULL) {
palette <- if (!is.null(range)) {
function(n) seq(range[1], range[2], length.out = n)

Check warning on line 63 in R/scale-alpha.R

View check run for this annotation

Codecov / codecov/patch

R/scale-alpha.R#L63

Added line #L63 was not covered by tests
} else {
NULL
}
discrete_scale("alpha", name = name, palette = palette, ...)
}

#' @rdname scale_alpha
#' @export
#' @usage NULL
scale_alpha_datetime <- function(name = waiver(), ..., range = c(0.1, 1)) {
scale_alpha_datetime <- function(name = waiver(), ..., range = NULL) {
palette <- if (!is.null(range)) pal_rescale(range) else NULL
datetime_scale(
aesthetics = "alpha", transform = "time", name = name,
palette = pal_rescale(range),
...
palette = palette, ...
)
}

#' @rdname scale_alpha
#' @export
#' @usage NULL
scale_alpha_date <- function(name = waiver(), ..., range = c(0.1, 1)){
scale_alpha_date <- function(name = waiver(), ..., range = NULL){
palette <- if (!is.null(range)) pal_rescale(range) else NULL
datetime_scale(
aesthetics = "alpha", transform = "date", name = name,
palette = pal_rescale(range),
...
palette = palette, ...
)
}
216 changes: 123 additions & 93 deletions R/scale-colour.R
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
#' you want to manually set the colors of a scale, consider using
#' [scale_colour_gradient()] or [scale_colour_steps()].
#'
#' @inheritParams continuous_scale
#' @param ... Additional parameters passed on to the scale type
#' @param type One of the following:
#' * "gradient" (the default)
Expand Down Expand Up @@ -77,122 +78,81 @@
#' v
#' options(ggplot2.continuous.fill = tmp) # restore previous setting
#' @export
scale_colour_continuous <- function(...,
scale_colour_continuous <- function(..., aesthetics = "colour",
guide = "colourbar", na.value = "grey50",
type = getOption("ggplot2.continuous.colour")) {
type <- type %||% "gradient"
args <- list2(...)
args$call <- args$call %||% current_call()

if (is.function(type)) {
if (!any(c("...", "call") %in% fn_fmls_names(type))) {
args$call <- NULL
}
check_scale_type(exec(type, !!!args), "scale_colour_continuous", "colour")
} else if (identical(type, "gradient")) {
exec(scale_colour_gradient, !!!args)
} else if (identical(type, "viridis")) {
exec(scale_colour_viridis_c, !!!args)
} else {
cli::cli_abort(c(
"Unknown scale type: {.val {type}}",
"i" = "Use either {.val gradient} or {.val viridis}."
))
if (!is.null(type)) {
scale <- scale_backward_compatibility(
..., guide = guide, na.value = na.value, scale = type,
aesthetic = "colour", type = "continuous"
)
return(scale)

Check warning on line 90 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L90

Added line #L90 was not covered by tests
}

continuous_scale(
aesthetics, palette = NULL, guide = guide, na.value = na.value,
...
)
}

#' @rdname scale_colour_continuous
#' @export
scale_fill_continuous <- function(...,
scale_fill_continuous <- function(..., aesthetics = "fill", guide = "colourbar",
na.value = "grey50",
type = getOption("ggplot2.continuous.fill")) {
type <- type %||% "gradient"
args <- list2(...)
args$call <- args$call %||% current_call()

if (is.function(type)) {
if (!any(c("...", "call") %in% fn_fmls_names(type))) {
args$call <- NULL
}
check_scale_type(exec(type, !!!args), "scale_fill_continuous", "fill")
} else if (identical(type, "gradient")) {
exec(scale_fill_gradient, !!!args)
} else if (identical(type, "viridis")) {
exec(scale_fill_viridis_c, !!!args)
} else {
cli::cli_abort(c(
"Unknown scale type: {.val {type}}",
"i" = "Use either {.val gradient} or {.val viridis}."
))
if (!is.null(type)) {
scale <- scale_backward_compatibility(
..., guide = guide, na.value = na.value, scale = type,
aesthetic = "fill", type = "continuous"
)
return(scale)

Check warning on line 110 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L110

Added line #L110 was not covered by tests
}

continuous_scale(
aesthetics, palette = NULL, guide = guide, na.value = na.value,
...
)
}

#' @export
#' @rdname scale_colour_continuous
scale_colour_binned <- function(...,
scale_colour_binned <- function(..., aesthetics = "colour", guide = "coloursteps",
na.value = "grey50",
type = getOption("ggplot2.binned.colour")) {
args <- list2(...)
args$call <- args$call %||% current_call()
if (is.function(type)) {
if (!any(c("...", "call") %in% fn_fmls_names(type))) {
args$call <- NULL
}
check_scale_type(exec(type, !!!args), "scale_colour_binned", "colour")
} else {
type_fallback <- getOption("ggplot2.continuous.colour", default = "gradient")
# don't use fallback from scale_colour_continuous() if it is
# a function, since that would change the type of the color
# scale from binned to continuous
if (is.function(type_fallback)) {
type_fallback <- "gradient"
}
type <- type %||% type_fallback

if (identical(type, "gradient")) {
exec(scale_colour_steps, !!!args)
} else if (identical(type, "viridis")) {
exec(scale_colour_viridis_b, !!!args)
} else {
cli::cli_abort(c(
"Unknown scale type: {.val {type}}",
"i" = "Use either {.val gradient} or {.val viridis}."
))
}
if (!is.null(type)) {
scale <- scale_backward_compatibility(
..., guide = guide, na.value = na.value, scale = type,
aesthetic = "colour", type = "binned"
)
return(scale)

Check warning on line 129 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L129

Added line #L129 was not covered by tests
}

binned_scale(
aesthetics, palette = NULL, guide = guide, na.value = na.value,
...
)
}

#' @export
#' @rdname scale_colour_continuous
scale_fill_binned <- function(...,
scale_fill_binned <- function(..., aesthetics = "fill", guide = "coloursteps",
na.value = "grey50",
type = getOption("ggplot2.binned.fill")) {
args <- list2(...)
args$call <- args$call %||% current_call()
if (is.function(type)) {
if (!any(c("...", "call") %in% fn_fmls_names(type))) {
args$call <- NULL
}
check_scale_type(exec(type, !!!args), "scale_fill_binned", "fill")
} else {
type_fallback <- getOption("ggplot2.continuous.fill", default = "gradient")
# don't use fallback from scale_colour_continuous() if it is
# a function, since that would change the type of the color
# scale from binned to continuous
if (is.function(type_fallback)) {
type_fallback <- "gradient"
}
type <- type %||% type_fallback

if (identical(type, "gradient")) {
exec(scale_fill_steps, !!!args)
} else if (identical(type, "viridis")) {
exec(scale_fill_viridis_b, !!!args)
} else {
cli::cli_abort(c(
"Unknown scale type: {.val {type}}",
"i" = "Use either {.val gradient} or {.val viridis}."
))
}
if (!is.null(type)) {
scale <- scale_backward_compatibility(
..., guide = guide, na.value = na.value, scale = type,
aesthetic = "fill", type = "binned"
)
return(scale)

Check warning on line 148 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L148

Added line #L148 was not covered by tests
}
}

binned_scale(
aesthetics, palette = NULL, guide = guide, na.value = na.value,
...
)
}

# helper function to make sure that the provided scale is of the correct
# type (i.e., is continuous and works with the provided aesthetic)
Expand Down Expand Up @@ -222,3 +182,73 @@

scale
}

# helper function for backwards compatibility through setting defaults
# scales through `options()` instead of `theme()`.
scale_backward_compatibility <- function(..., scale, aesthetic, type) {
aesthetic <- standardise_aes_names(aesthetic[1])

args <- list2(...)
args$call <- args$call %||% caller_call() %||% current_call()

if (type == "binned") {
fallback <- getOption(
paste("ggplot2", type, aesthetic, sep = "."),
default = "gradient"
)
if (is.function(fallback)) {
fallback <- "gradient"

Check warning on line 200 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L200

Added line #L200 was not covered by tests
}
scale <- scale %||% fallback
}

if (is_bare_string(scale)) {
if (scale == "continuous") {
scale <- "gradient"

Check warning on line 207 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L207

Added line #L207 was not covered by tests
}
if (scale == "discrete") {
scale <- "hue"

Check warning on line 210 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L210

Added line #L210 was not covered by tests
}
if (scale == "viridis") {
scale <- switch(
type, discrete = "viridis_d", binned = "viridis_b", "viridis_c"
)

Check warning on line 215 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L213-L215

Added lines #L213 - L215 were not covered by tests
}

candidates <- paste("scale", aesthetic, scale, sep = "_")
for (candi in candidates) {
f <- find_global(candi, env = caller_env(), mode = "function")
if (!is.null(f)) {
scale <- f
break

Check warning on line 223 in R/scale-colour.R

View check run for this annotation

Codecov / codecov/patch

R/scale-colour.R#L222-L223

Added lines #L222 - L223 were not covered by tests
}
}
}

if (!is.function(scale) && type == "discrete") {
args$type <- scale
scale <- switch(
aesthetic,
colour = scale_colour_qualitative,
fill = scale_fill_qualitative
)
}

if (is.function(scale)) {
if (!any(c("...", "call") %in% fn_fmls_names(scale))) {
args$call <- NULL
}
if (!"..." %in% fn_fmls_names(scale)) {
args <- args[intersect(names(args), fn_fmls_names(scale))]
}
scale <- check_scale_type(
exec(scale, !!!args),
paste("scale", aesthetic, type, sep = "_"),
aesthetic,
scale_is_discrete = type == "discrete"
)
return(scale)
}

cli::cli_abort("Unknown scale type: {.val {scale}}")
}
Loading
Loading