Skip to content

allow ordered factors, arbitrary dimensions in bivariate color scales #42

Description

@wpetry

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:
image

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions