Color Theory Guide
This guide covers the color theory principles implemented in chromo-map and how to use them for creating harmonious color schemes.
Understanding Color Theory
Color theory is the science and art of using color. It explains how humans perceive color, how colors mix, match, or clash, and how colors convey meaning.
- Key Concepts
Hue: The pure color (red, blue, yellow, etc.)
Saturation: The intensity or purity of the color
Value/Brightness: How light or dark the color is
Lightness: Perceptual brightness in HSL space
The Color Wheel
The color wheel is the foundation of color theory:
from chromo_map import Color
# Primary colors (120° apart)
red = Color('#ff0000') # 0°
green = Color('#00ff00') # 120°
blue = Color('#0000ff') # 240°
print(f"Red hue: {red.hue:.0f}°")
print(f"Green hue: {green.hue:.0f}°")
print(f"Blue hue: {blue.hue:.0f}°")
Color Harmonies
chromo-map provides built-in color harmony generation:
Complementary Colors
Colors opposite on the color wheel (180° apart):
from chromo_map import Color, generate_color_palette
base = Color('#ff6b35') # Orange
# Get complementary color
complement = base.complementary()
print(f"Base: {base.hex}")
print(f"Complement: {complement.hex}")
# Generate complementary palette
comp_palette = generate_color_palette(
base_color=base,
scheme='complementary',
count=5
)
Analogous Colors
Colors adjacent on the color wheel (within 30° typically):
# Analogous colors create harmonious, peaceful schemes
analogous_palette = generate_color_palette(
base_color='#3498db', # Blue
scheme='analogous',
count=5
)
# Manual analogous colors
base = Color('#3498db')
analogous_manual = [
base.adjust_hue(-30), # Blue-green
base.adjust_hue(-15), # Slightly blue-green
base, # Base blue
base.adjust_hue(15), # Slightly blue-purple
base.adjust_hue(30) # Blue-purple
]
Triadic Colors
Three colors evenly spaced around the color wheel (120° apart):
# Triadic schemes are vibrant but balanced
triadic_palette = generate_color_palette(
base_color='#e74c3c', # Red
scheme='triadic',
count=3
)
# Manual triadic
base = Color('#e74c3c') # Red (~0°)
triadic_manual = [
base, # Red
base.adjust_hue(120), # Green
base.adjust_hue(240) # Blue
]
Split-Complementary
Base color plus two colors adjacent to its complement:
# More nuanced than pure complementary
split_comp_palette = generate_color_palette(
base_color='#f39c12', # Orange
scheme='split_complementary',
count=4
)
Tetradic (Rectangle)
Four colors forming a rectangle on the color wheel:
# Rich, diverse palettes
tetradic_palette = generate_color_palette(
base_color='#9b59b6', # Purple
scheme='tetradic',
count=4
)
Square
Four colors evenly spaced (90° apart):
# Bold, dynamic palettes
square_palette = generate_color_palette(
base_color='#2ecc71', # Green
scheme='square',
count=4
)
Monochromatic Schemes
Variations of a single hue using different saturation and brightness levels:
from chromo_map import Color, Gradient
base = Color('#3498db') # Blue
# Create monochromatic variations
monochromatic = [
base.adjust_saturation(-0.6).adjust_lightness(0.3), # Very light, desaturated
base.adjust_saturation(-0.3).adjust_lightness(0.15), # Light, slightly desaturated
base, # Base color
base.adjust_saturation(0.2).adjust_lightness(-0.15), # Darker, more saturated
base.adjust_saturation(0.4).adjust_lightness(-0.3) # Very dark, highly saturated
]
# Or use the built-in function
mono_palette = generate_color_palette(
base_color=base,
scheme='monochromatic',
count=5,
saturation_range=(0.3, 1.0),
brightness_range=(0.4, 1.0)
)
Advanced Color Relationships
Color Temperature
Warm vs. cool colors affect emotional response:
# Warm colors (reds, oranges, yellows)
warm_colors = [
Color('#ff4757'), # Red
Color('#ff6348'), # Orange-red
Color('#ff7675'), # Pink-red
Color('#fdcb6e'), # Yellow-orange
Color('#e17055') # Brown-orange
]
# Cool colors (blues, greens, purples)
cool_colors = [
Color('#0984e3'), # Blue
Color('#74b9ff'), # Light blue
Color('#00b894'), # Green
Color('#00cec9'), # Teal
Color('#6c5ce7') # Purple
]
Color Intensity and Mood
base = Color('#e74c3c') # Vibrant red
# Create mood variations
energetic = base.adjust_saturation(0.3).adjust_brightness(0.1) # More vibrant
calming = base.adjust_saturation(-0.5).adjust_lightness(0.2) # Muted, lighter
dramatic = base.adjust_saturation(0.2).adjust_brightness(-0.3) # Dark, intense
moods = {
'energetic': energetic.hex,
'calming': calming.hex,
'dramatic': dramatic.hex
}
Practical Applications
Brand Color Systems
def create_brand_system(primary_color):
"""Create a complete brand color system."""
primary = Color(primary_color)
return {
# Core brand colors
'primary': primary.hex,
'secondary': primary.complementary().hex,
'accent': primary.adjust_hue(60).hex,
# Monochromatic variations
'primary_light': primary.adjust_lightness(0.3).hex,
'primary_dark': primary.adjust_lightness(-0.3).hex,
# Neutral colors
'neutral_light': Color('#f8f9fa').hex,
'neutral_medium': Color('#6c757d').hex,
'neutral_dark': Color('#343a40').hex,
# Semantic colors (maintaining brand harmony)
'success': primary.adjust_hue(120).adjust_saturation(-0.2).hex,
'warning': primary.adjust_hue(45).hex,
'error': primary.adjust_hue(180).adjust_saturation(0.1).hex
}
# Example brand system
brand_colors = create_brand_system('#3498db')
for role, color in brand_colors.items():
print(f"{role}: {color}")
Data Visualization Palettes
def create_data_palette(base_color, n_categories):
"""Create palette for categorical data visualization."""
if n_categories <= 3:
# Use triadic for small numbers
return generate_color_palette(base_color, 'triadic', n_categories)
elif n_categories <= 4:
# Use square for medium numbers
return generate_color_palette(base_color, 'square', n_categories)
else:
# Use evenly spaced hues for larger numbers
base = Color(base_color)
hue_step = 360 / n_categories
return [base.adjust_hue(i * hue_step) for i in range(n_categories)]
# Create palette for 6 categories
data_colors = create_data_palette('#e74c3c', 6)
print([color.hex for color in data_colors])
Seasonal Color Schemes
# Spring palette - fresh, light, analogous greens and yellows
spring = generate_color_palette('#2ecc71', 'analogous', 5)
spring_adjusted = [color.adjust_lightness(0.2) for color in spring]
# Summer palette - warm, vibrant
summer_base = Color('#f39c12') # Orange
summer = [
summer_base.adjust_hue(-30), # Yellow-orange
summer_base, # Orange
summer_base.adjust_hue(30), # Red-orange
summer_base.adjust_hue(60), # Red
summer_base.adjust_hue(90) # Pink-red
]
# Autumn palette - warm, muted
autumn_base = Color('#d35400') # Dark orange
autumn = [color.adjust_saturation(-0.3) for color in
generate_color_palette(autumn_base, 'analogous', 5)]
# Winter palette - cool, high contrast
winter_base = Color('#2980b9') # Dark blue
winter = generate_color_palette(winter_base, 'complementary', 4)
Color Psychology
Different colors evoke different emotional responses:
# Psychological color associations
psychology_colors = {
'trust': Color('#3498db').hex, # Blue - trust, stability
'energy': Color('#e74c3c').hex, # Red - energy, passion
'growth': Color('#2ecc71').hex, # Green - growth, nature
'creativity': Color('#9b59b6').hex, # Purple - creativity, luxury
'optimism': Color('#f1c40f').hex, # Yellow - optimism, happiness
'sophistication': Color('#34495e').hex, # Dark gray - sophistication
'purity': Color('#ecf0f1').hex, # Light gray - purity, cleanliness
}
Analyzing Existing Palettes
Use chromo-map to analyze the harmony of existing color schemes:
from chromo_map import analyze_color_harmony
# Analyze a existing palette
existing_palette = ['#e74c3c', '#3498db', '#2ecc71', '#f39c12']
colors = [Color(hex_color) for hex_color in existing_palette]
harmony_analysis = analyze_color_harmony(colors)
print(f"Harmony type: {harmony_analysis.get('type', 'Unknown')}")
print(f"Overall score: {harmony_analysis.get('score', 'N/A')}")
Color Blindness Considerations
When applying color theory, consider color blindness:
# Colors that work well for color blind users
colorblind_safe = {
'red': Color('#d73027'), # Safe red
'orange': Color('#fc8d62'), # Orange (distinct from red)
'yellow': Color('#fee08b'), # Yellow
'green': Color('#1a9850'), # Safe green
'blue': Color('#313695'), # Blue
'purple': Color('#5e3c99'), # Purple
'brown': Color('#8c510a'), # Brown
'pink': Color('#fbb4b9') # Pink
}
# Test color separation
for name, color in colorblind_safe.items():
print(f"{name}: {color.hex} (H: {color.hue:.0f}°, S: {color.saturation:.2f})")
Best Practices
Start with Purpose: Choose colors based on the emotional response you want
Use the 60-30-10 Rule: 60% dominant color, 30% secondary, 10% accent
Test Harmony: Use chromo-map’s harmony functions to validate your choices
Consider Context: Colors look different depending on surrounding colors
Maintain Accessibility: Ensure adequate contrast ratios
Be Consistent: Establish a color system and stick to it
Test with Users: Real feedback is invaluable
Advanced Techniques
Color Interpolation
# Create smooth transitions between colors
start = Color('#e74c3c') # Red
end = Color('#3498db') # Blue
# Create gradient with specific number of steps
transition = Gradient([start, end], 10)
# Extract colors at specific points
quarter_point = transition[2] # 25% of the way
midpoint = transition[5] # 50% of the way
three_quarter = transition[7] # 75% of the way
Dynamic Color Adjustment
def adjust_for_accessibility(color, background, maintain_hue=True):
"""Adjust color for accessibility while maintaining character."""
from chromo_map import find_accessible_color, is_accessible
if is_accessible(color, background):
return Color(color)
if maintain_hue:
# Try adjusting saturation and brightness first
base = Color(color)
for sat_adj in [-0.2, -0.4, 0.2, 0.4]:
for bright_adj in [-0.2, -0.4, 0.2, 0.4]:
adjusted = base.adjust_saturation(sat_adj).adjust_brightness(bright_adj)
if is_accessible(adjusted, background):
return adjusted
# Fall back to automatic accessibility adjustment
return find_accessible_color(color, background)
This guide provides the foundation for understanding and applying color theory with chromo-map. The library’s functions implement these principles programmatically, making it easy to create beautiful, harmonious, and accessible color schemes.