-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Description
As previously mentioned in the discussion of #2239: It would be nice if default scales could be set via themes.
Currently, default scales are defined as functions that are named scale_
aesthetic
_
data-type
()
, where aesthetic
is the name of the aesthetic and data-type
represents the data type, i.e., continuous, discrete, date, etc. For example, scale_colour_discrete()
is the default scale function for discrete colors.
The definition of these defaults is distributed all over the scales code, because for some scales the default scale is the only scale that exists (example:
Line 31 in 77fc5c7
scale_alpha_discrete <- function(..., range = c(0.1, 1)) { |
Line 6 in 77fc5c7
scale_colour_discrete <- scale_colour_hue |
It would be nice if there were a way to change the defaults other than to change the global function definitions, and in particular if the defaults could be linked to the theme. For example, the theme could have an entry default_scales = list("scale_color_discrete" = scale_color_hue, "scale_color_continuous" = scale_color_gradient, ...)
that lists the default scales to be used with this theme.
In terms of implementation, I see two problems, and it's not clear to me how much of a hurdle they might be. First, the code that searches for the default scales currently doesn't have access to the theme:
Lines 1 to 20 in bcc3ae5
find_scale <- function(aes, x, env = parent.frame()) { | |
if (is.null(x)) { | |
return(NULL) | |
} | |
type <- scale_type(x) | |
candidates <- paste("scale", aes, type, sep = "_") | |
for (scale in candidates) { | |
scale_f <- find_global(scale, env, mode = "function") | |
if (!is.null(scale_f)) | |
return(scale_f()) | |
} | |
# Failure to find a scale is not an error because some "aesthetics" don't | |
# need scales (e.g. group), and it allows others to extend ggplot2 with | |
# their own aesthetics | |
return(NULL) | |
} |
It is called from this function:
Line 91 in bcc3ae5
scales_add_defaults <- function(scales, data, aesthetics, env) { |
which is called from here:
Line 214 in a7b3135
scales_add_defaults(plot$scales, data, aesthetics, plot$plot_env) |
and here:
Line 274 in a7b3135
scales_add_defaults(plot$scales, data, new, plot$plot_env) |
Second, it's not immediately clear to me whether we even have the complete theme by the time these functions are called. They are ultimately called in plot_build()
here:
Line 48 in 3f63d62
data <- by_layer(function(l, d) l$compute_aesthetics(d, plot)) |
If by that time the entire theme is assembled, then I assume it could be handed down through all these functions to the point where the scale is looked up. Otherwise, this proposal would be infeasible.