Skip to contents

Overview

The evanverse color palette system provides a professional-grade collection of scientifically-designed color palettes optimized for data visualization and bioinformatics applications. This comprehensive guide covers the complete workflow from palette discovery to advanced customization.

What You’ll Learn

  • Palette Architecture - Understand the type-based organization system
  • Naming Convention - Master the standardized naming structure
  • Complete Workflow - From creation to compilation to usage
  • Practical Applications - Real-world visualization examples
  • Best Practices - Professional tips for publication-quality figures

System Architecture

Palette Organization

The palette system is organized hierarchically:

inst/extdata/palettes/
├── sequential/         # One-directional gradients
│   ├── seq_blues.json
│   ├── seq_forest.json
│   └── ...
├── qualitative/        # Discrete categories
│   ├── qual_vivid.json
│   ├── qual_nejm_g.json
│   └── ...
└── diverging/          # Two-directional from center
    ├── div_fireice.json
    ├── div_sunset.json
    └── ...

Storage Format: Individual JSON files compiled into palettes.rds for fast loading.

Palette Types

Sequential Palettes (seq_*)

Purpose: Continuous data with one direction of change

Use Cases: - Heatmaps (gene expression) - Intensity gradients - Probability/density maps - Single-direction scales

Examples: seq_blues, seq_forest, seq_muted

Qualitative Palettes (qual_*)

Purpose: Categorical data without inherent order

Use Cases: - Cell types or tissue groups - Sample categories - Treatment groups - Pathway classifications

Examples: qual_vivid, qual_nejm_g, qual_pbmc_sc

Diverging Palettes (div_*)

Purpose: Data with meaningful midpoint (usually zero)

Use Cases: - Fold changes (up/down regulation) - Correlation matrices - Differential expression - Volcano plots

Examples: div_fireice, div_sunset, div_polar


Naming Convention

Standard Format

All palettes follow the type_name_source structure:

[type]_[name]_[source]
  │      │       │
  │      │       └─ Optional: Source identifier (_g, _rb, _met, _sc)
  │      └───────── Required: Descriptive name
  └──────────────── Required: Type prefix (seq_, qual_, div_)

The 5 Golden Rules

  1. All lowercase - No capital letters
  2. Underscore separators - Use _, not camelCase or dots
  3. Type prefix required - Must start with seq_, div_, or qual_
  4. No number suffixes - Color count belongs in metadata
  5. Source suffix only for adapted palettes - Credit external sources

See Also: vignette("palette-naming-convention") for complete specification

Examples

# ✅ GOOD
seq_blues           # Sequential blue gradient
qual_vivid          # Vivid qualitative palette
div_fireice         # Fire-ice diverging palette
qual_nejm_g         # NEJM palette from ggsci
seq_locuszoom       # LocusZoom-style sequential

# ❌ BAD
blues               # Missing type prefix
VividSet            # Capital letters
my.palette          # Dot separator
palette_12          # Number in name

Complete Workflow

1. Discover Palettes

List Available Palettes

# List all palettes by type
seq_palettes <- list_palettes(type = "sequential")
qual_palettes <- list_palettes(type = "qualitative")
div_palettes <- list_palettes(type = "diverging")

cat("Sequential Palettes (", length(seq_palettes), "):\n", sep = "")
#> Sequential Palettes (4):
cat("  ", paste(head(seq_palettes, 5), collapse = ", "), "...\n\n", sep = "")
#>   c("seq_blues", "seq_blush", "seq_forest", "seq_muted", "seq_hokusai2"), c("sequential", "sequential", "sequential", "sequential", "sequential"), c(3, 4, 4, 4, 6), list(c("#deebf7", "#9ecae1", "#3182bd"), c("#FFCDB2", "#FFB4A2", "#E5989B", "#B5828C"), c("#B2C9AD", "#91AC8F", "#66785F", "#4B5945"), c("#E2E0C8", "#A7B49E", "#818C78", "#5C7285"), c("#abc9c8", "#72aeb6", "#4692b0", "#2f70a1", "#134b73", "#0a3351"))...

cat("Qualitative Palettes (", length(qual_palettes), "):\n", sep = "")
#> Qualitative Palettes (4):
cat("  ", paste(head(qual_palettes, 5), collapse = ", "), "...\n\n", sep = "")
#>   c("qual_earthy", "qual_primary", "qual_softtrio", "qual_vintage", "qual_balanced"), c("qualitative", "qualitative", "qualitative", "qualitative", "qualitative"), c(3, 3, 3, 3, 4), list(c("#C64328", "#56BBA5", "#E3A727"), c("#C64328", "#2AA6C6", "#E3A727"), c("#E64B35B2", "#00A087B2", "#3C5488B2"), c("#96A0D9", "#D9BDAD", "#D9D5A0"), c("#5D83B4", "#9FD0E8", "#CDAE9D", "#959683"))...

cat("Diverging Palettes (", length(div_palettes), "):\n", sep = "")
#> Diverging Palettes (4):
cat("  ", paste(div_palettes, collapse = ", "), "\n", sep = "")
#>   c("div_contrast", "div_fireice", "div_polar", "div_sunset", "div_pinkgreen_rb", "div_earthy", "div_sage"), c("diverging", "diverging", "diverging", "diverging", "diverging", "diverging", "diverging"), c(2, 2, 2, 2, 3, 5, 7), list(c("#C64328", "#56BBA5"), c("#2AA6C6", "#C64328"), c("#8CB5D2", "#E18E8F"), c("#57A2FF", "#FF8000"), c("#E64B35B2", "#00A087B2", "#3C5488B2"), c("#283618", "#606C38", "#FEFAE0", "#DDA15E", "#BC6C25"), c("#EDEAE7", "#B1CABA", "#BBCDD7", "#BBAAB6", "#6D8092", "#504B54", "#0E0F0F"))
# Display the complete palette gallery
bio_palette_gallery()
Complete gallery of all available palettes organized by type

Complete gallery of all available palettes organized by type

Complete gallery of all available palettes organized by type

Complete gallery of all available palettes organized by type

Complete gallery of all available palettes organized by type

Complete gallery of all available palettes organized by type

2. Retrieve Palettes

Basic Retrieval

# Specify type explicitly for clarity
vivid_colors <- get_palette("qual_vivid", type = "qualitative")
cat("qual_vivid palette:\n")
#> qual_vivid palette:
print(vivid_colors)
#> [1] "#E64B35" "#4DBBD5" "#00A087" "#3C5488" "#F39B7F" "#8491B4" "#91D1C2"
#> [8] "#DC0000" "#7E6148"

# Get specific number of colors
blues_3 <- get_palette("seq_blues", type = "sequential", n = 3)
cat("\nseq_blues (3 colors):\n")
#> 
#> seq_blues (3 colors):
print(blues_3)
#> [1] "#deebf7" "#9ecae1" "#3182bd"

# Get all available colors (omit n parameter)
blues_all <- get_palette("seq_blues", type = "sequential")
cat("\nseq_blues (all", length(blues_all), "colors):\n")
#> 
#> seq_blues (all 3 colors):
print(blues_all)
#> [1] "#deebf7" "#9ecae1" "#3182bd"

Preview Palettes

# Save current par settings
oldpar <- par(no.readonly = TRUE)

# Preview different palette types
par(mfrow = c(2, 2), mar = c(3, 1, 2, 1))

# Qualitative
preview_palette("qual_vivid", type = "qualitative")
title("Qualitative: qual_vivid", cex.main = 1, font.main = 1)

# Sequential
preview_palette("seq_blues", type = "sequential")
title("Sequential: seq_blues", cex.main = 1, font.main = 1)

# Sequential - Another
preview_palette("seq_forest", type = "sequential")
title("Sequential: seq_forest", cex.main = 1, font.main = 1)

# Diverging
preview_palette("div_fireice", type = "diverging")
title("Diverging: div_fireice", cex.main = 1, font.main = 1)
Preview of different palette types with color swatches

Preview of different palette types with color swatches


# Restore par settings
par(oldpar)

3. Create Custom Palettes

Step-by-Step Creation

# Step 1: Determine palette type
# Is your data continuous (sequential),
# categorical (qualitative), or centered (diverging)?

# Step 2: Define colors
ocean_colors <- c("#006BA4", "#FF7F0E", "#2CA02C", "#D62728", "#9467BD")

# Step 3: Create palette with proper naming
create_palette(
  name = "qual_ocean",  # Follow type_name_source convention
  type = "qualitative",
  colors = ocean_colors,
  color_dir = system.file("extdata", "palettes", package = "evanverse")
)

# Step 4: Compile palettes.rds (see next section)

Naming Your Custom Palette

# ✅ CORRECT naming
create_palette(
  name = "qual_custom",      # type_name
  name = "seq_thermal",      # for sequential
  name = "div_warmcool",     # for diverging
  name = "qual_nejm_g"       # if adapted from ggsci
)

# ❌ INCORRECT naming
create_palette(
  name = "MyPalette",        # Missing type, capital letters
  name = "custom.colors",    # Dot separator
  name = "palette_12"        # Number suffix
)

Color Utilities

# Convert between HEX and RGB
hex_colors <- c("#FF6B6B", "#4ECDC4", "#45B7D1")

# HEX to RGB
rgb_matrix <- hex2rgb(hex_colors)
cat("HEX to RGB:\n")
#> HEX to RGB:
print(rgb_matrix)
#> $`#FF6B6B`
#>   r   g   b 
#> 255 107 107 
#> 
#> $`#4ECDC4`
#>   r   g   b 
#>  78 205 196 
#> 
#> $`#45B7D1`
#>   r   g   b 
#>  69 183 209

# RGB to HEX
hex_back <- rgb2hex(rgb_matrix)
cat("\nRGB to HEX:\n")
#> 
#> RGB to HEX:
cat(paste(hex_back, collapse = ", "), "\n")
#> #FF6B6B, #4ECDC4, #45B7D1

4. Compile Palettes

After creating or modifying palette JSON files, compile them into the fast-loading RDS format:

# Compile all palettes from JSON to palettes.rds
compile_palettes(
  palettes_dir = system.file("extdata", "palettes", package = "evanverse"),
  output_rds = system.file("extdata", "palettes.rds", package = "evanverse")
)

# Test the new palette
get_palette("qual_ocean")
preview_palette("qual_ocean", type = "qualitative")

Workflow Summary

1. CREATE     → create_palette() saves JSON file
                ↓
2. COMPILE    → compile_palettes() builds palettes.rds
                ↓
3. USE        → get_palette() loads from palettes.rds

Practical Applications

Qualitative: Categorical Data

# Sample categorical data
set.seed(123)
category_data <- data.frame(
  Group = rep(LETTERS[1:5], each = 20),
  Value = c(rnorm(20, 10, 2), rnorm(20, 15, 3), rnorm(20, 12, 2.5),
            rnorm(20, 18, 4), rnorm(20, 8, 1.5))
)

# Use qualitative palette
qual_colors <- get_palette("qual_vivid", type = "qualitative", n = 5)

ggplot(category_data, aes(x = Group, y = Value, fill = Group)) +
  geom_boxplot(alpha = 0.8, outlier.alpha = 0.6) +
  scale_fill_manual(values = qual_colors) +
  labs(
    title = "Qualitative Palette: Group Comparison",
    subtitle = "Using qual_vivid for categorical groups",
    x = "Experimental Group",
    y = "Measured Value"
  ) +
  theme_minimal() +
  theme(legend.position = "none")
Qualitative palette for categorical group comparison

Qualitative palette for categorical group comparison

Sequential: Continuous Data

# Generate expression matrix
set.seed(456)
genes <- paste0("Gene", 1:10)
samples <- paste0("S", 1:8)
expr_matrix <- matrix(rnorm(80, mean = 5, sd = 2), nrow = 10)
rownames(expr_matrix) <- genes
colnames(expr_matrix) <- samples

# Convert to long format
expr_long <- expand.grid(Gene = genes, Sample = samples)
expr_long$Expression <- as.vector(expr_matrix)

# Use sequential palette
seq_colors <- get_palette("seq_mobility", type = "sequential")

ggplot(expr_long, aes(x = Sample, y = Gene, fill = Expression)) +
  geom_tile(color = "white", linewidth = 0.5) +
  scale_fill_gradientn(
    colors = seq_colors,
    name = "Expression"
  ) +
  labs(
    title = "Sequential Palette: Gene Expression Heatmap",
    subtitle = "Using seq_blues for continuous expression data"
  ) +
  theme_minimal() +
  theme(panel.grid = element_blank())
Sequential palette for continuous heatmap data

Sequential palette for continuous heatmap data

Diverging: Centered Data

# Generate fold change data
set.seed(789)
fc_data <- data.frame(
  Gene = paste0("Gene_", 1:20),
  LogFC = rnorm(20, 0, 1.2),
  Sample = rep(paste0("Sample_", 1:4), each = 5)
)

# Use diverging palette
div_colors <- get_palette("div_fireice", type = "diverging")

ggplot(fc_data, aes(x = Sample, y = Gene, fill = LogFC)) +
  geom_tile(color = "white", linewidth = 0.3) +
  scale_fill_gradientn(
    colors = div_colors,
    name = "Log2 FC",
    limits = c(-3, 3)
  ) +
  labs(
    title = "Diverging Palette: Fold Changes",
    subtitle = "Using div_fireice for centered data (zero midpoint)"
  ) +
  theme_minimal() +
  theme(panel.grid = element_blank())
Diverging palette for fold change data

Diverging palette for fold change data


Bioinformatics Applications

Palette Selection Guide

By Data Type

Gene Expression - Sequential: seq_blues, seq_forest for one-directional intensity - Diverging: div_fireice, div_sunset for fold changes

Single-Cell Data - Qualitative: qual_pbmc_sc for cell types - Sequential: seq_muted for UMAP/tSNE features

Pathway Analysis - Qualitative: qual_vivid, qual_pastel for pathways - Sequential: seq_blues for p-value gradients

Multi-omics - Qualitative: qual_vivid for distinct data types - Avoid red/green for colorblind accessibility

Multi-omics Example

# Simulate multi-omics data
set.seed(321)
omics_data <- data.frame(
  Sample = rep(paste0("P", 1:8), each = 3),
  DataType = rep(c("Transcriptome", "Proteome", "Metabolome"), 8),
  Intensity = c(
    rnorm(8, 100, 20),  # Transcriptome
    rnorm(8, 50, 15),   # Proteome
    rnorm(8, 25, 8)     # Metabolome
  ),
  Condition = rep(rep(c("Control", "Treatment"), each = 4), 3)
)

# Use qualitative palette for data types
omics_colors <- get_palette("qual_vivid", type = "qualitative", n = 3)
names(omics_colors) <- c("Transcriptome", "Proteome", "Metabolome")

ggplot(omics_data, aes(x = Sample, y = Intensity, fill = DataType)) +
  geom_bar(stat = "identity", position = "dodge", alpha = 0.85) +
  scale_fill_manual(values = omics_colors) +
  facet_wrap(~Condition, scales = "free_x") +
  labs(
    title = "Multi-omics Data Integration",
    subtitle = "Using qual_vivid to distinguish omics layers",
    x = "Patient Samples",
    y = "Normalized Intensity"
  ) +
  theme_minimal() +
  theme(
    axis.text.x = element_text(angle = 45, hjust = 1, size = 9),
    legend.position = "bottom"
  )
Multi-omics visualization with appropriate palette selection

Multi-omics visualization with appropriate palette selection


Advanced Techniques

Color Interpolation

# Get base colors from qualitative palette
base_colors <- get_palette("qual_vivid", type = "qualitative", n = 3)

# Interpolate to create smooth gradient
custom_gradient <- colorRampPalette(base_colors[1:2])(10)

# Visualize the gradient
gradient_df <- data.frame(
  x = 1:10,
  y = rep(1, 10),
  color = custom_gradient
)

ggplot(gradient_df, aes(x = x, y = y, fill = color)) +
  geom_tile(height = 0.5, width = 0.9) +
  scale_fill_identity() +
  labs(
    title = "Custom Color Interpolation",
    subtitle = "Creating gradients from qualitative palette colors"
  ) +
  theme_void() +
  theme(plot.title = element_text(hjust = 0.5))
Creating custom gradients through color interpolation

Creating custom gradients through color interpolation

Palette Combinations

# Combine palettes for complex visualizations
main_colors <- get_palette("qual_vivid", n = 4)
accent_color <- get_palette("div_fireice", n = 1)

# Use in multi-layer plots
ggplot(data) +
  geom_point(aes(color = group), size = 3) +
  geom_smooth(color = accent_color, linewidth = 1.5) +
  scale_color_manual(values = main_colors)

Best Practices

Accessibility Guidelines

Color Vision Deficiency - Test with colorblind simulators - Avoid red/green combinations alone - Use high contrast ratios (minimum 3:1) - Add texture/shape variations

Multi-Platform Compatibility - Test on different displays (mobile, print, projector) - Ensure sufficient color separation - Check grayscale conversion

Data Visualization - Match palette type to data type - Limit qualitative palettes to 8-10 categories - Use consistent colors across related plots - Reserve bright colors for emphasis

Performance Tips

# ✅ GOOD: Cache palette once
my_colors <- get_palette("qual_vivid", n = 5)
ggplot(data) + scale_fill_manual(values = my_colors)

# ❌ AVOID: Repeated calls
ggplot(data) + scale_fill_manual(values = get_palette("qual_vivid", n = 5))

Troubleshooting

Common Issues

Palette not found

# Check available palettes
list_palettes(type = "qualitative")

Not enough colors

# Check palette size
length(get_palette("qual_vivid"))

# Or use interpolation
colorRampPalette(get_palette("qual_vivid"))(20)

Colors don’t match

# Verify palette type
# Type is inferred from name prefix
get_palette("seq_blues")  # Automatically knows it's sequential

Custom palette not working

# Ensure you compiled after creation
compile_palettes(
  palettes_dir = system.file("extdata", "palettes", package = "evanverse"),
  output_rds = system.file("extdata", "palettes.rds", package = "evanverse")
)

Summary

Key Features

  • 80+ curated palettes organized by type
  • Standardized naming (type_name_source convention)
  • Flexible workflow from creation to compilation to usage
  • Scientific focus optimized for bioinformatics
  • Publication-ready professional quality

Quick Reference

# Discover
list_palettes(type = "sequential")
bio_palette_gallery()

# Retrieve
get_palette("seq_blues")
preview_palette("qual_vivid", type = "qualitative")

# Create
create_palette(
  name = "qual_custom",
  type = "qualitative",
  colors = c("#E64B35", "#4DBBD5", "#00A087")
)

# Compile
compile_palettes(
  palettes_dir = system.file("extdata", "palettes", package = "evanverse"),
  output_rds = system.file("extdata", "palettes.rds", package = "evanverse")
)

# Utilities
hex2rgb("#FF6B6B")
rgb2hex(matrix(c(255, 107, 107), nrow = 1))

Document Version: 2.0 Last Updated: 2025-11-12 Status: Official Documentation