biscale
biscale copied to clipboard
allow ordered factors, arbitrary dimensions in bivariate color scales
I would like to compose bivariate color scales with arbitrary dimensions to accommodate ordered factors. This feature would expand use of this package to a broader set of data that could benefit from a cross-classified color scale. For example, a bivariate color scale might allow an ordered factor (low vs. high) to be encoded as lightness or saturation variants of the other dimension's color scale.
I'm imagining a color scale that looks something like this:
Proposed solution
I think bi_class
is the main function that would need modification. The style
and dim
would gain the option of being specified as vectors of length 2 corresponding to the argument values to use for x and y. style
would also gain a new possible value, something like ordered
, factor
, or levels
. This option would retrieve the unique values of the variable rather than trying to calculate breaks as for a continuous variable. (Add a warning here if the variable isn't ordered.)
In the above figure, this solution would look something like: bi_class(.data, x = ord, y = cont, style = c("levels", "quantile"), dim = c(2, 3))
Some careful thought is needed to ensure that the color modification for the factor doesn't cause collisions. If willing to add a dependency, colorspace
has some nice functions for automating the calculation of lightened or desaturated colors for an arbitrary number of levels. An additional argument might allow the user to specify the type of color modification (lighten vs. desaturate) and the corresponding amounts of adjustment for each factor level (e.g., lightening 0 and 0.4).
Reprex The code below reproduces the figure above.
library(ggplot2)
library(colorspace)
library(patchwork)
pal <- c("#FECE65", "#E1640E", "#662506")
dat <- data.frame(y = factor(rep(c("<18", "18-45", ">45"), times = 2),
levels = c("<18", "18-45", ">45")),
x = factor(rep(c("low", "high"), each = 3),
levels = c("low", "high")))
dat$bi_class <- paste(as.integer(dat$x), as.integer(dat$y), sep = "-")
d <- ggplot(dat, aes(x = x, y = y, fill = bi_class))+
geom_tile()+
labs(title = "Desaturate", x = "[ordered factor]", y = "[continuous variable]")+
scale_fill_manual(values = c(desaturate(pal, amount = 0.7), pal))+
coord_equal(expand = FALSE)+
theme_minimal()+
theme(legend.position = "none")
l <- ggplot(dat, aes(x = x, y = y, fill = bi_class))+
geom_tile()+
labs(title = "Lighten", x = "[ordered factor]", y = "[continuous variable]")+
scale_fill_manual(values = c(lighten(pal, amount = 0.4), pal))+
coord_equal(expand = FALSE)+
theme_minimal()+
theme(legend.position = "none")
d + l