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