Skip to contents

Generates a named vector of colors for items grouped by a categorical variable. Each group is assigned a color "family" based on an HCL palette name, and colors for individual items within that group are generated by varying hue, chroma, and luminance around a base hue derived from the palette.

Usage

generate_grouped_palette(
  data,
  group_col,
  item_col,
  palette_map,
  default_side = "both",
  cmax = 80,
  luminance = c(40, 80),
  power = 1.2,
  shuffle = FALSE,
  seed = 42,
  increase_separation = FALSE,
  hue_span = 25,
  c_range = c(25, 85),
  l_range = c(40, 80)
)

Arguments

data

A data frame containing grouping and item columns.

group_col

Character string specifying the column containing group labels.

item_col

Character string specifying the column containing item names (each item receives a unique color).

palette_map

Named list mapping group names to HCL palette names (see grDevices::hcl.pals()). Example: list(GroupA = "YlOrBr", GroupB = "BuPu", GroupC = "Greens").

default_side

Character string specifying which side of a diverging palette to use when determining the base hue. One of "both", "left", "right", "low", or "high". (default: "both")

cmax

Numeric value controlling maximum chroma when sampling the base palette to determine a representative hue. (default: 80)

luminance

Numeric value or length-2 vector controlling luminance. If length 2, defines the luminance range used to generate colors (e.g. c(45, 80)). (default: c(40, 80))

power

Numeric value controlling the shape of sequential/diverging HCL palettes when deriving the base hue. (default: 1.2)

shuffle

Logical; if TRUE, randomly shuffles colors within each group. (default: FALSE)

seed

Integer seed used for reproducible shuffling. (default: 42)

increase_separation

Logical indicating whether to increase perceptual separation between colours within a group by spreading hues and alternating luminance/chroma values. (default: FALSE)

hue_span

Numeric controlling the width (in degrees) of the hue band around the palette's base hue used to generate colors within a group. (default: 25)

c_range

Numeric vector of length 2 specifying the chroma range used when generating colors (default values typically between 20 and 80 give visually pleasing results). (default: c(25, 85))

l_range

Numeric vector of length 2 specifying the luminance range used when generating colors. Restricting luminance (e.g. c(45, 80)) helps avoid colors that are too dark or too close to white. (default: c(40, 80))

Value

A named character vector of hex colors, where names correspond to the unique values of item_col.

Details

Colors are generated in the HCL (Hue–Chroma–Luminance) color space using polarLUV. Compared with RGB or HSV color models, HCL is designed to better reflect human color perception, meaning that changes in luminance and chroma correspond more closely to perceived differences between colors. This makes HCL particularly suitable for data visualisation where many categories must be distinguishable.

For each group, a base hue is derived from the specified HCL palette. Colors for individual items are then generated within a narrow hue band around this base hue while varying luminance and chroma. When increase_separation = TRUE, the function spreads hues slightly and alternates luminance and chroma values to increase perceptual separation between neighbouring colors.

Colors are generated in HCL space using polarLUV and converted to hex values. If a color falls outside the displayable sRGB gamut, chroma is reduced automatically until a valid color is obtained.

When increase_separation = TRUE, the function increases perceptual differences between neighbouring colors by spreading hues slightly and alternating luminance and chroma values. This typically improves readability when many items must be distinguished within the same group.

Examples

if (FALSE) { # \dontrun{
example_data <- data.frame(
  Type = rep(c("soil", "moss"), each = 5),
  Description = paste0("item_", 1:10)
)

pal <- generate_grouped_palette(
  data = example_data,
  group_col = "Type",
  item_col = "Description",
  palette_map = list(
    soil = "YlOrBr",
    moss = "BuPu"
  ),
  increase_separation = TRUE,
  hue_span = 30,
  c_range = c(25, 70),
  luminance = c(45, 80)
)

print(pal)
} # }