---
title: "Color Palette System"
subtitle: "Comprehensive Guide to the evanverse Palette Ecosystem"
author: "evanverse package"
date: "`r Sys.Date()`"
output:
  html_document:
    toc: true
    toc_depth: 3
    toc_float: true
    theme: flatly
    highlight: tango
    code_folding: show
vignette: >
  %\VignetteIndexEntry{Color Palette System}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r setup, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  echo = TRUE,
  warning = FALSE,
  message = FALSE,
  fig.width = 10,
  fig.height = 6,
  dpi = 300,
  out.width = "100%"
)

library(evanverse)
library(ggplot2)
library(dplyr)
```

# 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

```r
# ✅ 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

```{r discover-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 = "")
cat("  ", paste(head(seq_palettes, 5), collapse = ", "), "...\n\n", sep = "")

cat("Qualitative Palettes (", length(qual_palettes), "):\n", sep = "")
cat("  ", paste(head(qual_palettes, 5), collapse = ", "), "...\n\n", sep = "")

cat("Diverging Palettes (", length(div_palettes), "):\n", sep = "")
cat("  ", paste(div_palettes, collapse = ", "), "\n", sep = "")
```

### View Complete Gallery

```{r palette-gallery, fig.cap="Complete gallery of all available palettes organized by type", fig.height=12}
# Display the complete palette gallery
bio_palette_gallery()
```

## 2. Retrieve Palettes

### Basic Retrieval

```{r retrieve-palettes}
# Specify type explicitly for clarity
vivid_colors <- get_palette("qual_vivid", type = "qualitative")
cat("qual_vivid palette:\n")
print(vivid_colors)

# Get specific number of colors
blues_3 <- get_palette("seq_blues", type = "sequential", n = 3)
cat("\nseq_blues (3 colors):\n")
print(blues_3)

# Get all available colors (omit n parameter)
blues_all <- get_palette("seq_blues", type = "sequential")
cat("\nseq_blues (all", length(blues_all), "colors):\n")
print(blues_all)
```

### Preview Palettes

```{r preview-palettes, fig.cap="Preview of different palette types with color swatches"}
# 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)

# Restore par settings
par(oldpar)
```

## 3. Create Custom Palettes

### Step-by-Step Creation

```{r custom-creation, eval=FALSE}
# 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

```r
# ✅ 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

```{r 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")
print(rgb_matrix)

# RGB to HEX
hex_back <- rgb2hex(rgb_matrix)
cat("\nRGB to HEX:\n")
cat(paste(hex_back, collapse = ", "), "\n")
```

## 4. Compile Palettes

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

```{r compile-workflow, eval=FALSE}
# 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

```{r qual-example, fig.cap="Qualitative palette for categorical group comparison"}
# 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")
```

## Sequential: Continuous Data

```{r seq-example, fig.cap="Sequential palette for continuous heatmap 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())
```

## Diverging: Centered Data

```{r div-example, fig.cap="Diverging palette for fold change 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())
```

---

# 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

```{r multiomics-example, fig.cap="Multi-omics visualization with appropriate palette selection"}
# 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"
  )
```

---

# Advanced Techniques

## Color Interpolation

```{r interpolation, fig.cap="Creating custom gradients through 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))
```

## Palette Combinations

```{r combinations, eval=FALSE}
# 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

```{r performance-tips, eval=FALSE}
# ✅ 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**
```{r troubleshoot-1, eval=FALSE}
# Check available palettes
list_palettes(type = "qualitative")
```

**Not enough colors**
```{r troubleshoot-2, eval=FALSE}
# Check palette size
length(get_palette("qual_vivid"))

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

**Colors don't match**
```{r troubleshoot-3, eval=FALSE}
# Verify palette type
# Type is inferred from name prefix
get_palette("seq_blues")  # Automatically knows it's sequential
```

**Custom palette not working**
```{r troubleshoot-4, eval=FALSE}
# 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

```{r quick-reference, eval=FALSE}
# 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))
```

## Related Documentation

- **Naming Convention**: `vignette("palette-naming-convention")` - Complete naming standards
- **Package Guide**: `vignette("get-started")` - General evanverse overview
- **Function Reference**: `?get_palette`, `?create_palette`, `?compile_palettes`

---

**Document Version**: 2.0
**Last Updated**: `r Sys.Date()`
**Status**: Official Documentation
