Skip to contents

Introduction

The huerd package provides a scientifically-grounded approach to generating categorical color palettes. It uses a pure minimax optimization algorithm in the perceptually uniform OKLAB color space to create palettes with maximally distinct colors.

This vignette will walk you through the core features of huerd, from basic palette generation to in-depth analysis.

Installation

You can install the development version of huerd from GitHub with:

# install.packages("remotes")
# remotes::install_github("sims1253/huerd")

Basic Palette Generation

The simplest way to use huerd is with the generate_palette() function. By default, it will create a palette of the specified size with colors that are as distinct as possible.

library(huerd)

# Generate a palette of 5 colors
palette <- generate_palette(5, progress = FALSE)
print(palette)
#> 
#> -- huerd Color Palette (5 colors) --
#> Colors:
#> [ 1] #002B62
#> [ 2] #9900FF
#> [ 3] #FF0041
#> [ 4] #FFCE00
#> [ 5] #00FFFF
#> 
#> -- Quality Metrics Summary --
#> * Min. Perceptual Distance (OKLAB): 0.264
#> * Optimizer Performance Ratio      : 64.2%
#> * Min. CVD-Safe Distance (OKLAB)  : 0.227
#> 
#> -- Generation Details --
#> * Optimizer Iterations: 307
#> * Optimizer Status: NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs (above) was reached.

All palettes are automatically sorted by brightness (lightness in the OKLAB space), making them intuitive to use.

Constrained Palettes

A key feature of huerd is the ability to include fixed “brand” colors in your palette while optimizing the remaining colors around them.

# Generate a 6-color palette that must include a specific blue and orange
brand_palette <- generate_palette(
  n = 6,
  include_colors = c("#4A6B8A", "#E5A04C"),
  progress = FALSE
)
print(brand_palette)
#> 
#> -- huerd Color Palette (6 colors) --
#> Colors:
#> [ 1] #4A3509
#> [ 2] #4A6B8A
#> [ 3] #009AFF
#> [ 4] #E5A04C
#> [ 5] #00F2FF
#> [ 6] #FFF662
#> 
#> -- Quality Metrics Summary --
#> * Min. Perceptual Distance (OKLAB): 0.197
#> * Optimizer Performance Ratio      : 53.9%
#> * Min. CVD-Safe Distance (OKLAB)  : 0.185
#> 
#> -- Generation Details --
#> * Optimizer Iterations: 269
#> * Optimizer Status: NLOPT_XTOL_REACHED: Optimization stopped because xtol_rel or xtol_abs (above) was reached.

Palette Analysis

huerd includes powerful tools for analyzing the quality of your palettes.

evaluate_palette()

The evaluate_palette() function provides a detailed, quantitative assessment of a palette’s properties.

# Evaluate the brand palette we just created
evaluation <- evaluate_palette(brand_palette)
print(evaluation)
#> 
#> -- huerd Palette Evaluation (6 colors) --
#> 
#> -- Perceptual Distances (OKLAB) --
#> * Min distance       : 0.1969
#> * Mean distance      : 0.3562
#> * Median distance    : 0.3232
#> * Std. Dev.          : 0.1313
#> * Estimated Max Min  : 0.3655 (for unconstrained palette of this size)
#> * Performance Ratio  : 53.9% (achieved min / estimated max)
#> 
#> -- CVD Safety (OKLAB distances under simulation) --
#> * Worst-case min dist: 0.1851
#>   Protanopia : min=0.204, preserved_ratio=1.04
#>   Deuteranopia: min=0.185, preserved_ratio=0.94
#>   Tritanopia : min=0.186, preserved_ratio=0.94
#> 
#> -- Color Distribution (OKLAB) --
#> * Lightness (L)    : range=[0.34, 0.95], mean=0.69
#> * Chroma (C)       : range=[0.063, 0.183], mean=0.126
#> * Hue (degrees)    : circular_variance=0.737

This function returns a wealth of information, including:

  • Perceptual Distances: Minimum, mean, and other statistics about the distances between colors.
  • CVD Safety: How the palette performs under simulated color vision deficiency.
  • Color Distribution: Statistics on the spread of lightness, chroma, and hue.

plot_palette_analysis()

For a more visual analysis, the plot_palette_analysis() function creates a comprehensive dashboard.

# Create the diagnostic dashboard
plot_palette_analysis(brand_palette)

This dashboard provides six key visualizations:

  1. Color Swatches: An overview of the palette with key metrics.
  2. Pairwise Distance Matrix: A heatmap showing the perceptual distance between every pair of colors.
  3. Nearest Neighbor Distances: A bar chart showing how distinct each color is from its closest neighbor.
  4. OKLAB Color Space: A projection of the colors in the a*b* plane of the OKLAB space.
  5. CVD Simulation: How the palette appears to individuals with the three most common types of color vision deficiency.
  6. Comparative Palettes: A comparison of your palette’s distance distribution against established palettes like Viridis and Set2.

CVD Accessibility

huerd provides two main tools for working with CVD.

is_cvd_safe()

This function provides a simple, programmatic check to see if a palette meets a minimum threshold for CVD safety.

is_cvd_safe(brand_palette)
#> [1] TRUE

simulate_palette_cvd()

This function allows you to see how your palette would appear to individuals with different types of CVD.

# Simulate the appearance for all CVD types
cvd_simulation <- simulate_palette_cvd(brand_palette, cvd_type = "all")
print(cvd_simulation)
#> 
#> -- huerd CVD Simulation Result (Multiple Types, Severity: 1.00) --
#> Palette for: original
#>   [ 1] #4A3509
#>   [ 2] #4A6B8A
#>   [ 3] #009AFF
#>   [ 4] #E5A04C
#>   [ 5] #00F2FF
#>   [ 6] #FFF662
#> Palette for: protan
#>   [ 1] #3D3503
#>   [ 2] #5E6C8B
#>   [ 3] #67A0FF
#>   [ 4] #B7A443
#>   [ 5] #DEE7FF
#>   [ 6] #FFEE50
#> Palette for: deutan
#>   [ 1] #423B0B
#>   [ 2] #566589
#>   [ 3] #3F8DFD
#>   [ 4] #C7B54E
#>   [ 5] #C1D2FF
#>   [ 6] #FFF46B
#> Palette for: tritan
#>   [ 1] #512F2D
#>   [ 2] #307275
#>   [ 3] #00B3C0
#>   [ 4] #F98F8E
#>   [ 5] #00FCF6
#>   [ 6] #FFE7D7

Conclusion

This vignette has covered the core functionality of the huerd package. By combining pure minimax optimization with comprehensive analysis tools, huerd provides a powerful and flexible solution for creating high-quality, accessible color palettes.