Color for Data Visualization
The third encoding axis, used with intent
Color carries meaning: categorical palettes for groups, sequential scales for rank, diverging scales for above/below. Chosen deliberately and colorblind-safe, it encodes without misleading.
What you will learn
- Choose categorical, sequential or diverging scales
- Avoid rainbow and hue-after-hue traps
- Verify colorblind accessibility
What is this?
Color is a channel, not decoration: categorical palettes distinguish classes; sequential scales (light→dark) rank magnitude; diverging scales (two poles ± midpoint) show above/below. Rules: never rainbow for continuous, respect colorblind pairs (use blue/orange, not red/green), and give color one job per chart.
Why do you need it?
- Rainbow continuous scales imply order and distance that don't exist.
- Red/green comparisons are illegible to a large share of readers.
- Deliberate scales make the chart's structure self-explanatory.
- Accessible charts are a professional floor, not a bonus.
Mental model
Road signs using one color code
Color in data
Traffic systems don't paint meanings randomly — red means stop, amber warns, green goes; one code, everyone reads it. Data color palettes are the same: sequential light→dark means 'more', diverging colors signal 'two poles', categorical colors merely 'different kinds'.
How it works
- Categorical: distinct hues with equal lightness, ≤ ~7 classes.
- Sequential: a single hue light→dark (perceptually uniform) for magnitude.
- Diverging: two hues from a neutral midpoint (e.g., blue-white-red).
- Rainbow: avoid — hue passes through unrelated colors between values.
- Accessibility: Okabe-Ito or viridis palettes; test with a colorblind sim.
- One role per chart color: category or magnitude or emphasis — never more.
Scale type by question.
Examples
Choosing scales with seaborn
import seaborn as snscat = sns.color_palette("Set2") # categoricalseq = sns.color_palette("viridis", 9) # sequential, magnitudediv = sns.color_palette("RdBu_r") # diverging with midpointprint("categorical:", cat)print("colorblind-safe-ish sequential and diverging ready")Palette families map to questions: Set2 for classes, viridis for ordered magnitude, RdBu_r for above/below-midpoint.
In production
- A KPI heatmap uses a single sequential viridis scale so cell darkness = size.
- An experiment dashboard encodes lift with a blue-white-red diverging scale at zero.
- A plan-mix report reuses a 3-hue categorical palette consistently across pages.
Best practices
- Let the palette encode one role and force it consistently across a report.
- Choose blue/orange over red/green for safe accessible comparison.
- Sequential only light→dark; diverging always with an explicit midpoint definition.
- Test palettes with a colorblind simulator before publishing.
Common mistakes
- Rainbow (jet) scales — order by hue is unreadable and unethical on maps.
- Diverging where data is only positive — a sequential scale should be there.
- Red/green for good/bad when blue/orange reads for far more people.
- Evacuating hue so often that no single meaning survives.
Debugging tips
- A chart 'unreadable' by a colleague → run the palette through a colorblind sim.
- A heatmap confusing → check the scale type vs the question (mag vs class).
- Frequent mid spectrum ambiguity → a perceptually ordered viridis usually rescues it.
- Ask: if printed grayscale, does meaning survive? If not, color is load-bearing — encode elsewhere too.
Interview checkpoint
Quick quiz
Best palette for a number getting larger (100→1000):
Red/Green is a safe universal comparison pair.