47 min read

In Chapter 2, we ranked visual channels by perceptual accuracy. Position came first. Length came second. Color was somewhere in the middle of the hierarchy, weaker than position for communicating exact quantities but potent for a different reason...

Learning Objectives

  • Distinguish between the three types of color palettes (sequential, diverging, categorical) and identify when each is appropriate
  • Explain why perceptually uniform colormaps (viridis) are superior to rainbow colormaps (jet) for continuous data
  • Design colorblind-accessible visualizations (8% of men are red-green colorblind)
  • Identify and avoid common color mistakes: rainbow colormaps, too many categorical colors, color without meaning, low-contrast combinations
  • Apply color theory principles: hue for categories, luminance for ordered data, saturation for emphasis
  • Select and test color palettes using standard tools (ColorBrewer, Coolors, coblis colorblind simulator)

Chapter 3: Color — The Most Powerful and Most Abused Visual Variable

"Color is information, not decoration." — This chapter's thesis, and from now on, yours.

In Chapter 2, we ranked visual channels by perceptual accuracy. Position came first. Length came second. Color was somewhere in the middle of the hierarchy, weaker than position for communicating exact quantities but potent for a different reason: color is the first thing people notice. Before your viewer reads a title, before they trace an axis, before they decode a single data point, they see color. It hits the visual system in under 200 milliseconds. It carries emotional weight. It triggers associations — danger, nature, warmth, corporate authority — that no other visual channel can match.

This makes color the most powerful visual variable in your toolkit.

It also makes color the most abused. No other design decision in data visualization is gotten wrong more often, more confidently, or with worse consequences. The rainbow colormap. The twelve-color categorical legend that nobody can decode. The red-green traffic light palette that eight percent of your male audience cannot distinguish. The heatmap where adjacent values look identical because the palette has perceptual dead zones. The dashboard where every chart uses a different color for the same category.

This chapter will change how you think about color. Not art-school color theory — we are not painting sunsets. This is perception-science color: the principles that determine whether your audience can accurately read data from a colored chart. By the end of this chapter, you will understand why most default color choices are wrong, and you will have a systematic process for choosing palettes that are accurate, accessible, and honest.

No code in this chapter. The science comes first. When we reach Part III, you will implement every concept here in matplotlib, seaborn, and beyond. For now, we build the judgment that makes those implementations meaningful.


3.1 Why Color Is Special

Color is not just another item on the list of visual channels from Chapter 2. It occupies a unique position in human perception for three reasons.

First, color is pre-attentive. As we established in Chapter 2, pre-attentive features are processed by the visual system before conscious attention kicks in. A single red data point in a field of gray ones will pop out instantly. You do not search for it; your visual cortex hands it to you. This makes color extraordinarily effective for drawing attention to specific elements — outliers, alerts, categories that need to stand out.

Second, color carries semantic meaning. No other visual channel does this as strongly. A longer bar just means "more." A higher position just means "higher value." But red means danger, stop, loss, heat, Republican (in the United States), or Labour (in the United Kingdom). Green means go, growth, safety, nature. Blue means calm, corporate, cold, Democrat. These associations are partly biological, partly cultural, and entirely unavoidable. When you put color on a chart, you are not just encoding data — you are activating a web of associations in your viewer's mind. Ignore those associations and your chart will confuse. Leverage them and your chart becomes intuitive.

Third, color is actually three variables pretending to be one. This is the threshold concept of this chapter, and it is the single most important idea you will take from it. When someone says "change the color," they could mean any of three perceptually distinct dimensions:

  • Hue — the wavelength of light. Red, blue, green, orange, purple. What most people mean when they say "color."
  • Luminance (also called lightness or value) — how bright or dark the color is. Dark navy versus pale sky blue. A dark forest green versus a light mint.
  • Saturation (also called chroma or intensity) — how vivid or washed-out the color is. A pure, saturated red versus a muted, grayish pink.

Each of these three dimensions communicates different kinds of information, and each is suited to different data types. Hue is an identity channel — it says "this is different from that." Luminance is a magnitude channel — it says "this is more than that." Saturation is a weak magnitude channel — it can suggest intensity, but human perception is poor at judging precise saturation differences.

The fundamental error that ruins most color choices is treating these three dimensions as interchangeable. They are not. Using hue (rainbow colors) to represent a continuous, ordered quantity is like using the shape channel (circles, squares, triangles) to represent numerical magnitude. The channel does not match the data type. This mismatch is the root cause of the rainbow colormap problem, the too-many-categories problem, and most of the other color mistakes we will dissect in this chapter.

Threshold Concept — Color Is Three Variables

Color is not a single visual variable. It is three: hue, luminance, and saturation. Each has a specific job. Hue encodes categories (nominal data). Luminance encodes ordered magnitude (sequential data). Saturation provides emphasis but is unreliable for precise encoding. Using the wrong color dimension for your data type is the most common color mistake in visualization — and now you know how to diagnose it.


3.2 The Three Color Dimensions: Hue, Luminance, Saturation

Let us examine each dimension in detail, because your ability to make good color decisions depends on understanding what each one can and cannot do.

3.2.1 Hue: The Identity Dimension

Hue is what most people mean when they say "color." It corresponds roughly to the dominant wavelength of light: red, orange, yellow, green, cyan, blue, violet. Hue is categorical by nature. There is no inherent ordering to hues — red is not "more than" blue, and green is not "between" red and blue in any perceptual sense. (Yes, the visible light spectrum has a physical ordering by wavelength, but human perception does not treat hue as a linear scale. We will see why this matters when we discuss rainbow colormaps.)

What hue encodes well: Nominal categories. Product lines. Countries. Experimental conditions. Political parties. Any variable where the values are labels, not quantities. When you assign red to Product A and blue to Product B, hue says: "these are different things." It does not say anything about which is bigger, better, or more.

What hue encodes badly: Ordered data. If you use a rainbow of hues (red, orange, yellow, green, blue, purple) to represent temperature from cold to hot, you are asking the viewer to interpret a categorical channel as a magnitude channel. The viewer's visual system will see boundaries between hues rather than a smooth gradient. They will perceive the yellow-to-green transition differently from the green-to-blue transition, even if the underlying data steps are equal. This is the fundamental problem with rainbow colormaps, which we will examine at length in Section 3.4.

How many hues can you use? Research consistently shows that viewers can reliably distinguish and remember about five to eight categorical hues. Beyond eight, the legend becomes a lookup table, and the viewer must constantly shift their gaze between the chart and the legend, destroying the pre-attentive advantage of color. If your categorical variable has more than about seven or eight levels, you need a different strategy: grouping, faceting (small multiples, which we will cover in Chapter 8), or interactive filtering.

3.2.2 Luminance: The Magnitude Dimension

Luminance — how light or dark a color is — is the workhorse of color encoding for ordered data. Unlike hue, luminance has a natural, intuitive ordering: darker means more, lighter means less (or vice versa, depending on the palette). This ordering is stable across cultures and robust across viewing conditions.

What luminance encodes well: Sequential quantitative data. A heatmap of sales revenue, where darker cells represent higher revenue. A choropleth map of population density, where darker regions are more densely populated. Any variable that goes from low to high (or high to low) maps naturally onto a light-to-dark gradient.

Why luminance matters for accessibility: Luminance is the dimension of color that survives almost all forms of color vision deficiency. A person with deuteranopia (the most common form of red-green colorblindness) cannot distinguish red from green by hue, but they can still distinguish dark red from light red by luminance. This is why the luminance-first principle — always ensure your palette has a clear luminance gradient, regardless of hue — is the single most important rule for accessible color design.

Why luminance matters for printing: When a color chart is printed in grayscale (and this happens far more often than you think — photocopied handouts, black-and-white journal articles, cheap office printers), only the luminance channel survives. If your palette relies on hue differences alone (same lightness, different hues), it will collapse to a uniform gray in grayscale. If your palette has a clear luminance gradient, the ordering will remain legible even without color.

3.2.3 Saturation: The Emphasis Dimension

Saturation — how vivid or muted a color is — is the weakest of the three dimensions for data encoding. Human perception is poor at making precise judgments about saturation differences. You can tell "very vivid" from "very muted," but you cannot reliably distinguish five or six levels of saturation the way you can distinguish five or six levels of luminance.

What saturation is good for: Emphasis and de-emphasis. If you want to highlight one category while pushing others into the background, desaturate the background categories to gray and leave the focal category in full saturation. This is the "gray out everything except the story" technique, and it is one of the most powerful storytelling tools in visualization. We will use it extensively in Chapter 9 when we discuss data storytelling.

What saturation is bad for: Encoding quantitative data. A palette that goes from pale pink to vivid red is actually varying both saturation and luminance simultaneously. The luminance difference is doing most of the perceptual work. If you tried to create a palette that varied only in saturation (same hue, same luminance, different saturation), the steps would be difficult to distinguish.

Check Your Understanding

  1. You have a dataset with a variable called "region" with values North, South, East, West, Central. Which color dimension should you use to encode it, and why?
  2. You have a variable called "temperature" ranging from 10 to 40 degrees Celsius. Which color dimension should drive the encoding, and why?
  3. A colleague creates a heatmap where all cells have the same luminance but different hues (pure red, pure green, pure blue, pure yellow). What will happen when the chart is printed in grayscale?

3.3 Three Palette Types for Three Data Types

Now that you understand the three dimensions of color, we can map them to the three fundamental palette types used in data visualization. This mapping is not arbitrary — it follows directly from the principle that your encoding channel must match your data type.

3.3.1 Sequential Palettes: For Ordered Data Going One Direction

A sequential palette represents data that ranges from low to high (or from few to many, small to large, infrequent to frequent). The palette uses a single hue — or a narrow range of hues — that varies primarily in luminance, from light (low values) to dark (high values).

Characteristics of a good sequential palette:

Property Requirement
Luminance gradient Monotonically increasing or decreasing — no reversals, no flat spots
Hue range Narrow (single hue or closely related hues)
Perceptual uniformity Equal data steps produce equal perceptual steps
Colorblind safety Safe by design, since the encoding is driven by luminance, not hue
Grayscale survival Excellent — the luminance gradient is preserved

Common sequential palettes and their properties:

Palette Name Hue Range Lightness Range Notes
viridis Yellow to blue-purple Light to dark Perceptually uniform, colorblind-safe, the gold standard since 2015
plasma Yellow to deep magenta Light to dark Higher contrast than viridis, good for dense heatmaps
inferno Pale yellow to near-black through red Very light to very dark Maximum luminance range, strong in print
cividis Yellow to dark blue Light to dark Designed specifically for deuteranopia and protanopia accessibility
Blues (ColorBrewer) White to dark blue Very light to dark Classic single-hue sequential, excellent for choropleth maps
YlOrRd (ColorBrewer) Pale yellow to dark red Light to dark Multi-hue sequential with warm tones, good for "heat" data
Greys White to black Full range Maximum grayscale fidelity, best for print-only contexts

When to use sequential palettes:

  • Temperature readings (0 to 100)
  • Population density (low to high)
  • Revenue figures (small to large)
  • Concentration levels (dilute to concentrated)
  • Any single continuous variable with a natural low-to-high ordering

When NOT to use sequential palettes:

  • Data that deviates from a meaningful center point (use diverging instead)
  • Categorical data (use qualitative instead)
  • Data where both extremes are equally important and the midpoint is the baseline

3.3.2 Diverging Palettes: For Data That Deviates from a Center

A diverging palette represents data that extends in two directions from a meaningful midpoint. The palette uses two distinct hues — one for each direction — with luminance increasing toward the extremes and the midpoint rendered in a neutral, light color (often white or pale gray).

Characteristics of a good diverging palette:

Property Requirement
Two hue anchors Distinct, contrasting hues at the two extremes
Luminance symmetry Equal steps above and below the midpoint produce equal perceptual changes
Neutral midpoint A light, desaturated color (white, pale gray) at the center
Meaningful center The midpoint must correspond to a real value in the data (zero, average, baseline)
Colorblind safety The two hue anchors must be distinguishable by colorblind viewers — blue-to-red is far safer than green-to-red

Common diverging palettes and their properties:

Palette Name Negative Hue Positive Hue Midpoint Colorblind Safe?
RdBu (ColorBrewer) Blue Red White Yes — blue and red are distinguishable in all common CVD types
RdYlGn (ColorBrewer) Green Red Yellow No — fails for deuteranopia and protanopia
BrBG (ColorBrewer) Teal-green Brown White Yes — brown and teal differ in both hue and luminance
coolwarm (matplotlib) Blue Red Light gray Yes — designed for perceptual uniformity
PiYG (ColorBrewer) Yellow-green Pink White Marginal — depends on the number of steps

When to use diverging palettes:

  • Temperature anomalies (cooler than average vs. warmer than average)
  • Profit and loss (negative vs. positive)
  • Election margins (one party vs. the other)
  • Sentiment scores (negative vs. positive)
  • Any variable where deviation from a meaningful baseline is the story

The critical requirement: The midpoint of a diverging palette must correspond to a meaningful value in the data. If you center a red-white-blue palette at zero but your data ranges from 10 to 50, you have created a palette where the entire visible range maps to one half of the diverging scale. The result will look like a sequential blue palette with a confusing white spot, because no data values fall on the red side. Always check that your data actually straddles the midpoint.

Common Pitfall — Diverging Palettes on Non-Centered Data

One of the most common color mistakes is applying a diverging palette to data that has no meaningful center point. If you are showing absolute revenue by region (all positive values, no natural midpoint), a diverging palette will mislead: it will imply that some regions are "negative" when they are simply lower. Use a sequential palette instead. Reserve diverging palettes for data where the direction of deviation (above or below center) carries meaning.

3.3.3 Categorical (Qualitative) Palettes: For Nominal Data

A categorical palette (also called a qualitative palette) represents nominal data — categories with no inherent order. The palette uses distinct hues at similar luminance and saturation levels, maximizing the perceptual distance between colors so that each category is easily distinguishable.

Characteristics of a good categorical palette:

Property Requirement
Hue diversity Maximally distinct hues, spread around the color wheel
Luminance uniformity All colors at approximately the same lightness — no category should visually dominate
Saturation uniformity All colors at approximately the same vividness
Maximum categories 7 to 8 before the palette becomes unreliable
No implied ordering Hues should not suggest a sequence (avoid rainbow ordering)

Common categorical palettes and their properties:

Palette Name Number of Colors Notes
Set2 (ColorBrewer) 8 Muted, accessible, excellent for professional contexts
Paired (ColorBrewer) 12 Paired light/dark versions of 6 hues — good for matched categories
tab10 (matplotlib) 10 The matplotlib 2.0+ default, decent distinguishability
Dark2 (ColorBrewer) 8 Higher saturation than Set2, strong in small chart elements
Set1 (ColorBrewer) 9 Vivid, high saturation — can be overwhelming in large areas
Category20 (various) 20 Too many to reliably distinguish — avoid unless interactive with tooltips

The cardinal rule of categorical color: do not use more than about seven or eight colors. This is not an arbitrary guideline. It is grounded in the same research on visual working memory that limits our ability to track distinct items. With more than eight categories, viewers must repeatedly consult the legend, and pre-attentive color discrimination breaks down. If your data has fifteen categories, you have a design problem, not a palette problem. Solutions include:

  • Group small categories into an "Other" bucket
  • Use faceting (small multiples) to reduce the number of categories per panel
  • Use a single highlight color for the categories of interest and gray for everything else
  • Provide interactive filtering so the viewer can explore subsets

Best Practice — The "Gray + Highlight" Strategy

When you have many categories but your story is about one or two of them, render all categories in a neutral gray and use a saturated color only for the categories you want to highlight. This leverages the pop-out effect from Chapter 2: the colored elements will jump out of the gray field instantly. The viewer gets the context (all categories are present) without the cognitive load of decoding a twelve-color legend.

Check Your Understanding

  1. Meridian Corp's quarterly report needs to show revenue for five product lines over the past three years. Which palette type should you use for the product lines? Why?
  2. The same report includes a heatmap of year-over-year revenue change (some product lines grew, others shrank). Which palette type now?
  3. Your colleague uses a 15-color categorical palette for 15 sales regions. What is wrong with this, and what would you recommend instead?

3.4 The Rainbow Colormap Problem

If this chapter has a villain, it is the rainbow colormap. Known as "jet" in matplotlib, "rainbow" in other tools, and "HSV" in yet others, this colormap uses the full spectrum of hues — red, orange, yellow, green, cyan, blue, violet — to represent continuous data. It is probably the most widely used colormap in the history of scientific visualization. It is also terrible. This section explains exactly why, with evidence, not just opinion.

3.4.1 What the Rainbow Colormap Does

The rainbow colormap maps data values to positions on the color spectrum. Low values get blue or violet. High values get red. The middle gets green and yellow. It looks vivid and eye-catching. For decades, it was the default in MATLAB, matplotlib, and many other tools. It seemed like an obvious choice: the rainbow is a natural ordering of light, so surely it represents ordered data well.

It does not. The rainbow colormap fails on every criterion that matters for data visualization.

3.4.2 Failure 1: Perceptual Non-Uniformity

A perceptually uniform colormap produces equal perceptual changes for equal data changes. If the temperature rises by one degree, the color should change by the same perceptual amount regardless of whether you are going from 10 to 11 degrees or from 30 to 31 degrees.

The rainbow colormap violates this catastrophically. Human perception is not equally sensitive to all hue transitions. The transition from blue to cyan is perceptually small — the two colors look similar to most viewers. The transition from yellow to green is also perceptually small. But the transition from green to yellow is perceptually large — it creates a sharp, visible boundary even when the underlying data changes smoothly.

The result: the rainbow colormap creates false boundaries. Viewers see bands of color and interpret them as real features in the data — plateaus, edges, boundaries — that do not exist. A smooth temperature gradient rendered in rainbow will appear to have distinct "zones," and viewers will perceive the yellow-green boundary as a sharp transition even if the underlying temperature field is perfectly smooth.

This is not a minor aesthetic issue. In medical imaging, false color boundaries in rainbow colormaps have been shown to affect diagnostic accuracy. In fluid dynamics visualization, artificial color banding can mask or mimic real turbulence structures. In any domain where the viewer needs to perceive smooth gradients and locate real features, the rainbow colormap lies.

3.4.3 Failure 2: No Luminance Monotonicity

Remember that luminance is the dimension that encodes "how much." A good sequential colormap has monotonically increasing (or decreasing) luminance — it gets steadily darker (or lighter) from one end to the other.

The rainbow colormap has no consistent luminance ordering. Yellow is the lightest hue. Blue and red are darker. Green and cyan fall somewhere in between. The luminance profile of the rainbow colormap is a mess: it rises to a peak at yellow, drops through green, flattens through cyan, drops again through blue. This means the colormap is not sequentially ordered in the dimension that actually encodes magnitude. A viewer's intuitive sense of "lighter = less, darker = more" is violated.

3.4.4 Failure 3: Useless in Grayscale

Convert a rainbow colormap to grayscale and it becomes nearly unreadable. Because the luminance profile is non-monotonic, the grayscale version shows a bright stripe in the middle (the yellow band) flanked by darker regions on both sides. It looks like a diverging colormap, not a sequential one. The viewer cannot recover the ordering of the data from the grayscale version.

For any visualization that might be printed, photocopied, or viewed by someone with severe color vision deficiency (achromatopsia), the rainbow colormap is useless.

3.4.5 Failure 4: Colorblind-Hostile

The rainbow colormap uses both red-green and blue-yellow contrasts, which means it fails for every major type of color vision deficiency. For a viewer with deuteranopia (the most common form of colorblindness), the red and green portions of the rainbow are indistinguishable. The colormap collapses to a palette that looks roughly like dark-brown, yellow, light-brown — losing most of the information in the middle of the range.

3.4.6 Why It Persists

If the rainbow colormap is this bad, why does it remain so popular? Several reasons:

  1. Defaults. Until 2015, jet was the default colormap in matplotlib. MATLAB used a similar default for decades. Defaults are powerful — most users never change them.
  2. Aesthetics. The rainbow is vivid and eye-catching. It looks "scientific." It makes posters stand out at conferences. The fact that it looks good is precisely what makes it dangerous — it is optimized for visual appeal, not perceptual accuracy.
  3. Tradition. "We've always used rainbow for this type of data." Entire subfields have decades of publications using rainbow colormaps. Changing the convention means published figures look different from historical ones.
  4. Ignorance. Most scientists and analysts never receive formal training in color perception. They choose palettes by how they look on screen, not by how they encode data.

None of these reasons justify using a colormap that introduces false features into data and excludes colorblind viewers. The evidence is overwhelming and has been published repeatedly since at least the 1990s. Borland and Taylor's 2007 paper "Rainbow Color Map (Still) Considered Harmful" documented the perceptual failures exhaustively. The visualization community has reached consensus: rainbow colormaps should not be used for continuous data.

Common Pitfall — "But My Field Uses Rainbow"

Some scientific domains have decades of published figures using rainbow colormaps (atmospheric science, oceanography, medical imaging). If you work in one of these fields, you may face pushback when you switch to a perceptually uniform palette. The answer is not to capitulate. The answer is to use a perceptually uniform palette in your new work and, when necessary, include a rainbow version in a supplementary figure for comparison with historical literature. The field will catch up. Some already have — meteorology has been migrating to perceptually uniform palettes since the early 2010s.

Real-World Application — matplotlib's Default Change

In 2015, matplotlib changed its default colormap from jet (rainbow) to viridis — a perceptually uniform, colorblind-safe colormap designed by Stéfan van der Walt and Nathaniel Smith. This was one of the most consequential decisions in the history of open-source data visualization. Every matplotlib figure created with default settings after this change was immediately more perceptually accurate and more accessible. We examine this story in detail in Case Study 1.


3.5 Designing for Colorblindness

Approximately 8% of men and 0.5% of women of Northern European descent have some form of color vision deficiency (CVD). Worldwide, that is roughly 300 million people. If you create a visualization for an audience of 100 people, the expected number of colorblind viewers is about 4. In a conference room of 25, there is probably one. In a lecture hall of 200, there are about 8.

Designing for colorblindness is not an edge case. It is a baseline professional requirement.

3.5.1 How Color Vision Works (Briefly)

Normal human color vision is trichromatic: the retina contains three types of cone cells, each sensitive to a different range of wavelengths. The L-cones (long wavelength) peak in the red-yellow region. The M-cones (medium wavelength) peak in the green region. The S-cones (short wavelength) peak in the blue-violet region. The brain reconstructs color perception from the relative activation of these three cone types.

Color vision deficiency occurs when one or more cone types are absent or have shifted sensitivity.

3.5.2 Types of Color Vision Deficiency

Type Affected Cones Prevalence (Males) Prevalence (Females) Effect on Perception
Deuteranopia M-cones (green) absent ~5% ~0.4% Red and green become indistinguishable; both appear as shades of olive/brown/gold
Protanopia L-cones (red) absent ~2.5% ~0.05% Similar to deuteranopia; red appears dark; red-green confusion
Tritanopia S-cones (blue) absent ~0.01% ~0.01% Blue and yellow confusion; very rare
Anomalous trichromacy Cone sensitivity shifted Varies Varies Reduced color discrimination, not complete absence — the most common form of CVD
Achromatopsia All cones absent ~0.003% ~0.003% Complete color blindness; only luminance is perceived

The overwhelming majority of colorblind viewers have deuteranopia or protanopia — both are forms of red-green confusion. This means:

  • Red and green are the most dangerous color pair in visualization. Any chart that relies on distinguishing red from green will fail for roughly 7-8% of male viewers.
  • Traffic-light color schemes (red/yellow/green) are not accessible unless the colors also differ substantially in luminance.
  • The popular "red = bad, green = good" convention is broken for colorblind users.

3.5.3 The Luminance-First Principle

The single most effective strategy for colorblind accessibility is designing palettes where the primary information is carried by luminance, not hue. This works because:

  1. Luminance perception is independent of cone type. Even with complete absence of one cone type, the viewer can still perceive light-to-dark differences.
  2. Sequential palettes that go from light to dark in a single hue are inherently colorblind-safe (dark blue is distinguishable from light blue regardless of color vision status).
  3. Diverging palettes that use blue and red (rather than green and red) are accessible because blue and red differ in both hue and luminance for all common CVD types.

Best Practice — The Luminance-First Principle

When designing any color palette, ensure that luminance alone can convey the essential information. Test this by converting your chart to grayscale. If the grayscale version is still readable — if you can still tell which values are high and which are low, which regions belong to which category — then your palette will survive colorblindness and printing. If the grayscale version is a uniform gray mush, your palette is relying on hue alone, and it will fail for many viewers.

3.5.4 Safe and Unsafe Color Pairs

Safe color combinations for colorblind viewers:

Pair Why It Works
Blue and orange Differ in hue, luminance, and warmth — distinguishable by all CVD types
Blue and red Differ in wavelength extremes — robust across CVD types
Dark blue and light yellow High luminance contrast, different hues
Purple and green Generally distinguishable (purple has a blue component that remains visible)
Black and any bright color Maximum luminance contrast

Unsafe color combinations — avoid for critical distinctions:

Pair Why It Fails
Red and green The classic failure — indistinguishable for deuteranopia and protanopia
Green and brown Too similar in many CVD types
Blue and purple Very similar for tritanopia; also difficult in low luminance
Red and orange Can be confused by protanopia (both appear as similar warm tones)
Light green and light yellow Low contrast, easily confused by multiple CVD types

3.5.5 Testing Tools

You do not need to guess whether your palette is colorblind-safe. Use these tools:

coblis (Color Blindness Simulator): Upload an image of your chart and see how it appears under different types of color vision deficiency. Free, web-based, and immediately useful. At color-blindness.com/coblis-color-blindness-simulator.

ColorBrewer: Cynthia Brewer's indispensable tool (colorbrewer2.org) flags which palettes are colorblind-safe and which are not. Every palette in ColorBrewer has been tested.

Sim Daltonism (macOS): A macOS application that overlays a real-time color vision simulation on any window. Hold it over your chart and see what a colorblind viewer would see.

Chrome DevTools: Chrome's developer tools include a built-in vision deficiency simulator under the Rendering panel. This works on any web-based visualization.

Real-World Application — The Traffic Light Dashboard

A Meridian Corp product manager creates a KPI dashboard using red, yellow, and green circles to indicate "behind target," "at risk," and "on track." The dashboard is shown to the executive team. One VP consistently misinterprets the status indicators, flagging green items for review and ignoring red ones. After an awkward meeting, someone realizes the VP has deuteranopia. The fix: add shape encoding (circle for on track, triangle for at risk, square for behind target) and ensure the red has significantly lower luminance than the green. Redundant encoding — using multiple visual channels for the same information — is the professional standard for accessibility.

3.5.6 Redundant Encoding: The Belt-and-Suspenders Approach

The most robust approach to colorblind accessibility is not just choosing safe colors — it is encoding the same information in multiple visual channels. If color encodes category, also use shape, or pattern, or direct labels. If color encodes magnitude, also use luminance (which it should anyway, per the luminance-first principle) or add text annotations.

This redundancy has a bonus: it makes your chart more readable for everyone, not just colorblind viewers. In a busy chart, having two channels confirming the same information reduces errors and speeds comprehension.

Check Your Understanding

  1. A public health dashboard uses green to show "low risk" regions and red for "high risk" regions on a map. What percentage of your male audience may struggle to distinguish these? What would you change?
  2. Why is the luminance-first principle more robust than simply choosing "colorblind-safe" color pairs?
  3. What is redundant encoding, and why is it the gold standard for accessible design?

3.6 Color Mistakes That Ruin Charts

You now understand the theory. Let us catalog the specific mistakes you will encounter — in your own work and in the work of others — so you can recognize and fix them.

3.6.1 Mistake: The Rainbow Colormap for Continuous Data

Already discussed at length in Section 3.4. The fix: use viridis, inferno, plasma, cividis, or a well-designed sequential palette from ColorBrewer. There is no legitimate use case for a rainbow colormap on continuous ordered data.

3.6.2 Mistake: Too Many Categorical Colors

The symptom: a legend with twelve or fifteen color swatches, most of which look nearly identical in the actual chart. The viewer spends more time decoding the legend than reading the data.

Why it happens: The data has many categories, and the chart-maker assigns a unique color to each one without considering whether the viewer can distinguish them.

The fix:

  1. If the story is about all categories equally, use faceting (small multiples) with a single highlight color, one panel per category.
  2. If the story is about a few specific categories, use the gray-plus-highlight strategy.
  3. If the data truly needs all categories visible simultaneously, group the small ones into "Other" to bring the count below eight.
  4. If the chart is interactive, allow the user to hover or click to identify categories instead of relying on color alone.

3.6.3 Mistake: Color Without Meaning

The symptom: a bar chart where each bar is a different color, even though all bars represent the same variable (say, revenue by month). The colors add no information — they are purely decorative. Worse, they imply categorical distinctions that do not exist.

Why it happens: Chart-making tools sometimes default to cycling through a color palette even when there is only one data series. The chart-maker does not notice, or thinks the colors "look more interesting."

The fix: If the bars represent a single variable, use a single color. Reserve distinct colors for when they encode distinct categories. Every color in your chart should mean something. If a color does not carry information, it is noise.

Common Pitfall — "Chartjunk Color"

In Chapter 1, we introduced the concept of chart-junk — visual elements that add no information. Color applied without meaning is the most pervasive form of chart-junk. A pie chart with twelve vivid colors. A bar chart where each bar is a different shade for no reason. A line chart where the background is a gradient. Ask yourself: if I removed this color, would the viewer lose any information? If the answer is no, remove it.

3.6.4 Mistake: Low-Contrast Combinations

The symptom: text or data points that are difficult to read because the foreground color is too similar in luminance to the background color. Light yellow on white. Medium gray on light gray. Pale blue on pale green.

Why it happens: The chart looks fine on a high-quality monitor in a dimly lit room. It becomes unreadable on a projector in a bright conference room, or in a printed handout, or on a phone screen in sunlight.

The fix: Ensure a minimum luminance contrast ratio between foreground and background elements. The Web Content Accessibility Guidelines (WCAG) specify a minimum contrast ratio of 4.5:1 for normal text and 3:1 for large text. These ratios are a useful baseline for chart elements too. You can check contrast ratios using tools like WebAIM's Contrast Checker (webaim.org/resources/contrastchecker).

3.6.5 Mistake: Inconsistent Color Across a Dashboard or Report

The symptom: a dashboard with three charts. In chart one, blue represents the "Enterprise" product line. In chart two, blue represents the "East" region. In chart three, blue represents 2024 data. The viewer must re-learn the color encoding for every chart.

Why it happens: Each chart was designed independently, without a global color mapping.

The fix: Establish a consistent color-to-meaning mapping for your entire report, dashboard, or presentation. If blue means "Enterprise" in one chart, it means "Enterprise" in every chart. This is what we call a semantic color scheme, and it is the subject of Section 3.8.

3.6.6 Mistake: Cultural Color Assumptions

The symptom: a chart designed in one cultural context is shown to an international audience, and the color associations are misread.

Red means "loss" or "danger" in Western financial contexts. In Chinese and many East Asian cultures, red means "good fortune" and "prosperity." A stock market chart shown in red may signal "down" to a Western viewer and "up" to a Chinese viewer.

Green means "go" or "positive" in most Western contexts. In some South American cultures, green is associated with death. In Islamic contexts, green has deep religious significance.

The fix: Be aware of your audience's cultural context. For international audiences, rely on luminance and spatial encoding (up = good, down = bad) rather than hue-based value judgments. When using color for "good vs. bad" assessments, include explicit labels (text annotations, icons) rather than relying on color alone.

Ethical Analysis — When Color Hides Disparities

Color choices in choropleth maps (maps where regions are colored by data values) have profound ethical implications. Consider a public health map showing disease prevalence by county. If you choose a sequential palette with only three color steps (low, medium, high), you collapse wide variation within each band. A county with 5% prevalence and a county with 14% prevalence may receive the same color, hiding a nearly threefold difference. If you increase to seven or nine steps, you reveal the granularity — but some viewers may find the additional detail overwhelming.

The choice of how many steps to show in a color scale is an ethical decision. Fewer steps simplify the message but hide disparities. More steps reveal truth but risk cognitive overload. There is no formula that resolves this tension — but being aware that the tension exists is the first step toward handling it responsibly. We will return to this theme in Chapter 4 when we discuss lies, distortions, and honest charts.


3.7 Choosing and Testing Color Palettes: A Practical Workflow

Theory is necessary. Practice is where the work gets done. Here is a step-by-step workflow for selecting and testing color palettes for any visualization.

Step 1: Identify Your Data Type

Before touching a color picker, answer one question: what type of data am I encoding with color?

Data Type Example Palette Type
Sequential (ordered, one direction) Revenue, population, concentration Sequential
Diverging (ordered, two directions from center) Profit/loss, temperature anomaly, sentiment Diverging
Nominal (categories, no order) Product line, country, experimental group Categorical (qualitative)
Binary (two states) Yes/No, Pass/Fail, Male/Female Two-color subset of categorical

If you are not encoding data with color — if color is purely decorative — stop and ask whether you need color at all. Often you do not.

Step 2: Determine the Number of Levels

For categorical palettes, count your categories. If you have more than seven or eight, revisit your design (see Section 3.6.2). For sequential and diverging palettes, determine whether you need a continuous color ramp (for a heatmap or choropleth) or a discrete set of steps (for a classed choropleth).

Step 3: Select a Candidate Palette

Use established, tested palettes rather than inventing your own. The heavy lifting of perceptual science and accessibility testing has already been done for you.

ColorBrewer (colorbrewer2.org): The single most important resource for choosing color palettes for maps and charts. Created by Cynthia Brewer, a cartographer at Penn State, ColorBrewer offers sequential, diverging, and qualitative palettes in multiple step counts (3 to 12). Each palette is annotated with accessibility information: colorblind safe, print safe, photocopy safe. Start here.

The viridis family (matplotlib): viridis, plasma, inferno, magma, and cividis. All are perceptually uniform, colorblind-safe, and monotonic in luminance. viridis is the default in matplotlib since 2015 and is an excellent default choice for any sequential data.

Coolors (coolors.co): A palette generator that lets you browse, create, and adjust palettes. Useful for categorical palettes when you need a custom brand-aligned color scheme. Always test the result with the workflow below.

Scientific colour maps (Crameri): Fabio Crameri's collection of perceptually uniform, colorblind-safe scientific colormaps (scientificcolourmaps.org). These are designed specifically for scientific visualization and include sequential, diverging, and multi-sequential variants.

Step 4: Run the Grayscale Test

Convert your chart to grayscale. Does the ordering of the data remain clear? Can you distinguish the categories? If not, your palette relies too heavily on hue and not enough on luminance. Choose a palette with a stronger luminance gradient.

How to run this test: - Take a screenshot of your chart and desaturate it in any image editor. - In Python: convert the figure to grayscale by extracting the luminance channel. - On macOS: use the Accessibility settings to enable grayscale mode temporarily. - Ask yourself: "Can I still read the story from this chart?"

Step 5: Run the Colorblind Simulation

Upload your chart to coblis (color-blindness.com/coblis-color-blindness-simulator) or use Chrome DevTools' vision deficiency simulator. Check under deuteranopia (the most common type) and protanopia. Can you still distinguish all the categories? Can you still see the ordering in a sequential palette?

Step 6: Check Contrast

Ensure that all text, labels, and data elements have sufficient contrast against their backgrounds. Use a contrast checker tool and aim for the WCAG minimum of 4.5:1 for text and 3:1 for large elements.

Step 7: Test in Context

View the chart at the size and resolution it will be displayed. A palette that works at full-screen may fail when the chart is shrunk to a quarter-page figure in a report. Colors that look distinct on a high-DPI display may merge on a projector. If the chart will be printed, print a test copy.

Best Practice — The 5-Step Palette Selection Checklist

  1. Data type check. Is the palette type (sequential, diverging, categorical) correct for the data type?
  2. Grayscale test. Is the chart still readable when converted to grayscale?
  3. Colorblind simulation. Does the chart pass deuteranopia and protanopia simulation?
  4. Contrast check. Do all elements meet WCAG contrast minimums?
  5. Context test. Does the chart work at its actual display size and medium (screen, print, projection)?

3.8 Semantic Color and Organizational Palettes

The final dimension of color for data visualization is semantic meaning — what colors mean by convention, by context, or by organizational standard.

3.8.1 Semantic Color: When Conventions Help

Some color associations are so widely shared that leveraging them makes charts immediately more intuitive:

Color Common Semantic Associations Visualization Application
Red Danger, stop, loss, heat, urgency Negative values, declining metrics, high temperature, alerts
Green Safety, go, growth, nature Positive values, growth, target met, low risk
Blue Calm, cold, water, corporate, trust Cool temperatures, water-related data, neutral "safe" default
Yellow/Orange Caution, warmth, attention Warning states, moderate risk, transitional values
Gray Neutral, inactive, de-emphasized Context data, background, "not the story"

When to use semantic color: Use it when the association is universal (or at least universal for your audience) and when it reinforces the message. Blue for cold temperatures and red for hot temperatures is a semantic encoding that makes the chart immediately intuitive.

When semantic color goes wrong: Semantic associations are not universal. As discussed in Section 3.6.6, red means "good" in many East Asian financial contexts. "Green = environmentally friendly" is a Western association that does not translate everywhere. And in data visualization specifically, the red-green semantic pair is the worst possible choice for accessibility.

3.8.2 Organizational Palettes: Consistency Across a Brand

In professional settings, color consistency is a form of data integrity. When Meridian Corp's quarterly report uses the same five colors in the same mapping across every chart, slide, and dashboard, the viewer builds up a color vocabulary: dark blue is always Enterprise, teal is always SMB, orange is always Government. By the fifth chart, the viewer no longer needs the legend. The colors have become semantic within that document's context.

Building an organizational palette:

  1. Start with the organization's brand colors (usually 2-3 primary colors).
  2. Extend to 5-8 categorical colors by adding colors that harmonize with the brand but are perceptually distinct.
  3. Test the full set for colorblind accessibility and luminance distinctness.
  4. Create sequential and diverging variants by building luminance ramps from the primary brand colors.
  5. Document the palette with hex codes, RGB values, and usage guidelines.
  6. Enforce it by creating a theme file or style sheet that can be imported into matplotlib, seaborn, or your tool of choice.

This organizational palette work will be implemented in Chapter 32 (Theming and Branding), where we will build matplotlib style sheets and seaborn themes. For now, understand the principle: color consistency across related charts is not a luxury — it is a requirement for clear communication.

3.8.3 When Conventions Mislead

Semantic color can also mislead. Consider a financial report where an analyst chooses green for expenses and red for revenue, reversing the conventional meaning. The viewer's instinct (green = good, red = bad) fights the actual encoding (green = cost, red = income). The result is confusion and potential misinterpretation.

Or consider a political map where the analyst assigns colors based on aesthetic preference rather than established convention. In the United States, audiences expect blue = Democrat and red = Republican. Reversing this would cause confusion regardless of how clearly the legend is labeled, because the semantic association is stronger than the legend.

The rule: when a strong semantic convention exists, follow it or explicitly break it with prominent labeling. Do not silently violate conventions.

Real-World Application — Semantic Color in COVID Dashboards

During the COVID-19 pandemic, different organizations made strikingly different color choices for their case-count maps and dashboards. The New York Times used a sequential red palette that intensified with case counts, leveraging the semantic association of red with danger and urgency. Some government dashboards used a traffic-light scheme (green/yellow/red) that implied clear thresholds between "safe" and "unsafe" — thresholds that were often arbitrary and varied between jurisdictions. The Johns Hopkins dashboard used a dark red-to-bright red sequential palette on a dark background, creating a visual impression of severity that matched the seriousness of the data. We analyze these choices in detail in Case Study 2.


Chapter Summary

Color is not a single visual variable — it is three. This insight is the foundation of every good color decision.

Hue (red, blue, green) encodes categories — it is an identity channel. Use it for nominal data, limit it to seven or eight distinct values, and ensure the hues differ in luminance as well as wavelength.

Luminance (light to dark) encodes magnitude — it is a magnitude channel. Use it as the primary encoding for sequential and diverging data. Luminance survives colorblindness, grayscale printing, and low-quality displays. The luminance-first principle is the most important rule in this chapter.

Saturation (vivid to muted) provides emphasis but is unreliable for precise encoding. Use it for focus and de-emphasis, not for conveying quantitative differences.

Three palette types map to three data types: sequential (ordered one direction), diverging (ordered two directions from a center), and categorical (nominal, unordered). Choosing the wrong palette type for your data is a fundamental encoding error.

The rainbow colormap (jet) is perceptually non-uniform, creates false boundaries, fails in grayscale, and is hostile to colorblind viewers. Use viridis, inferno, cividis, or any well-designed alternative. There is no legitimate use case for rainbow on continuous data.

Colorblindness affects roughly 8% of men. The luminance-first principle, redundant encoding, and simulation testing are non-negotiable professional practices. Avoid red-green as a critical distinguishing pair.

Color mistakes that ruin charts: rainbow for continuous data, too many categorical colors, color without meaning, low contrast, inconsistent color across related charts, and unexamined cultural assumptions.

Semantic color leverages shared associations (red = danger, blue = cold) to make charts more intuitive, but it must be applied carefully because these associations are not universal.


Spaced Review: Revisiting Chapters 1 and 2

To strengthen your retention of earlier material, answer these questions before moving on:

  1. From Chapter 1: What is the difference between exploratory and explanatory visualization? How does color choice differ between the two contexts? (In exploratory work, you might use defaults and iterate quickly. In explanatory work, every color must be deliberate and meaningful.)

  2. From Chapter 2: Where does color fall in the Cleveland-McGill perceptual accuracy hierarchy? Why is it ranked lower than position and length for quantitative data? (Color — specifically, color saturation and hue — is less accurately perceived for quantitative comparisons than position along a common scale or length.)

  3. From Chapter 2: What is pre-attentive processing, and which dimension of color (hue, luminance, or saturation) produces the strongest pop-out effect? (Hue produces the strongest pop-out — a single red dot among blue dots is detected in under 200ms.)

  4. Connecting Chapters 2 and 3: In Chapter 2, we classified visual channels as identity channels (what is this?) and magnitude channels (how much?). Which color dimension is an identity channel? Which is a magnitude channel? (Hue is identity; luminance is magnitude; saturation is a weak magnitude channel.)


Progressive Project Checkpoint

Return to the "ugly" climate dataset plot from Chapter 1. Consider the three variables in the progressive project dataset:

Temperature anomalies (deviation from a 1951-1980 baseline): - Data type: diverging (values above and below a meaningful center) - Palette choice: a diverging palette centered on the baseline. Blue for cooler-than-average years, red for warmer-than-average years. This encoding leverages perceptual associations (cool = blue, warm = red) while remaining colorblind-accessible because blue and red are distinguishable for all common CVD types, and the palette relies on luminance difference at the extremes, not just hue. - Specific palette: RdBu (ColorBrewer) or coolwarm (matplotlib), reversed so that blue = below baseline and red = above baseline.

CO2 concentration (parts per million, monotonically increasing over time): - Data type: sequential (ordered, one direction) - Palette choice: a sequential palette with a clear luminance gradient. Lighter values for lower concentrations, darker for higher. - Specific palette: viridis or inferno. Both are perceptually uniform and colorblind-safe.

Data source categories (NOAA, CSIRO, Mauna Loa — categorical): - Data type: nominal (no ordering) - Palette choice: a qualitative palette with three distinct, equally prominent colors. - Specific palette: Set2 (ColorBrewer) — three muted, distinguishable colors with similar luminance.

In Chapter 10, when we begin coding in matplotlib, you will implement these palette choices. For now, record them in your project notebook. You have just made your first deliberate, science-grounded color decisions.


What's Next

In Chapter 4, we turn from how to show data honestly with color to the broader question of honesty in visualization. We will examine truncated axes, cherry-picked time ranges, area distortions, and the ethical obligations of anyone who controls the picture. The color principles from this chapter — especially the ethics of color choices that hide or reveal disparities — will thread directly into that discussion.


Key Terms Glossary

Term Definition
Sequential palette A color palette that represents ordered data going in one direction (low to high), using a luminance gradient within a single hue or narrow hue range
Diverging palette A color palette that represents data extending in two directions from a meaningful center point, using two hue anchors with a neutral midpoint
Categorical palette A color palette that represents nominal (unordered) categories using distinct hues at similar luminance and saturation levels; also called a qualitative palette
Perceptually uniform colormap A colormap where equal steps in data value produce equal steps in perceived color difference, regardless of position in the range
viridis A perceptually uniform, colorblind-safe colormap ranging from dark purple through blue and green to yellow; the default in matplotlib since 2015
Rainbow colormap (jet) A colormap that maps data to the full visible spectrum; perceptually non-uniform, creates false boundaries, and is colorblind-hostile
Colorblind accessibility The design practice of ensuring that color-encoded information remains interpretable for viewers with color vision deficiency
Deuteranopia The most common form of color vision deficiency, caused by absent M-cones (green); results in red-green confusion; affects ~5% of males
Protanopia A form of color vision deficiency caused by absent L-cones (red); results in red-green confusion with darkened reds; affects ~2.5% of males
Tritanopia A rare form of color vision deficiency caused by absent S-cones (blue); results in blue-yellow confusion; affects ~0.01% of the population
Color space A mathematical model that defines how colors are represented numerically; common spaces include RGB, HSL, and CIE LAB
RGB A color space that represents colors as combinations of Red, Green, and Blue light; the native space of displays but perceptually non-uniform
HSL A color space that represents colors as Hue, Saturation, and Lightness; more intuitive than RGB but still perceptually non-uniform
CIE LAB A color space designed to be perceptually uniform, where L represents lightness, a represents green-to-red, and b represents blue-to-yellow; the basis for measuring perceptual color differences
Luminance The perceived brightness of a color; the dimension of color that encodes magnitude and survives colorblindness and grayscale conversion
Hue The wavelength-based dimension of color (red, blue, green, etc.); best suited for encoding nominal categories
Saturation The vividness or purity of a color; useful for emphasis but unreliable for encoding precise data values
ColorBrewer A web-based tool (colorbrewer2.org) providing tested sequential, diverging, and qualitative color palettes with accessibility annotations; created by Cynthia Brewer
Color ramp A continuous gradient between two or more colors used to represent a range of data values
Color encoding The assignment of color properties to data values in a visualization
Semantic color Color used to leverage shared cultural or conventional associations (red = danger, blue = cold) to make a visualization more intuitive

Deep Dive: CIE LAB Color Spaces and the Math of Perceptual Uniformity

This section is for the Deep Dive learning path. Skip it on a first read if you are following the Standard or Fast Track paths.

To understand why some colormaps are perceptually uniform and others are not, you need to understand what "perceptually uniform" actually means in mathematical terms.

The Problem with RGB

The RGB color space represents colors as three intensities: red (0-255), green (0-255), blue (0-255). This space is designed for display hardware, not for human perception. A step from RGB(0, 0, 0) to RGB(0, 0, 20) (slightly brighter blue) does not look the same as a step from RGB(0, 0, 200) to RGB(0, 0, 220) (also slightly brighter blue, but at a higher baseline). The perceptual size of a step in RGB depends on where you are in the space. In technical terms, the RGB color space is not a metric space where Euclidean distance corresponds to perceptual difference.

HSL: Better Intuition, Same Problem

The HSL (Hue, Saturation, Lightness) color space rearranges RGB into a more intuitive cylindrical model: hue is an angle on a color wheel, saturation is the distance from the center, and lightness goes from black (bottom) to white (top). This makes it easy to say "same hue, different lightness" or "same lightness, different hue." But HSL is still perceptually non-uniform. A 10-degree step in hue from yellow to yellow-green does not look the same as a 10-degree step from blue to blue-purple. The human eye is more sensitive to some hue transitions than others.

CIE LAB: A Perceptual Color Space

In 1976, the International Commission on Illumination (CIE) defined the CIE LAB color space specifically to address perceptual non-uniformity. In CIE LAB:

  • L represents lightness, from 0 (black) to 100 (white)
  • a represents the green-to-red axis
  • b represents the blue-to-yellow axis

The space was designed so that the Euclidean distance between two points in LAB space approximates the perceived difference between the two colors. A distance of 1 unit in LAB space is approximately one "just noticeable difference" (JND) — the smallest color change a human observer can detect.

This is the basis for the deltaE metric (written as delta-E or dE), which is the Euclidean distance in CIE LAB space between two colors:

deltaE = sqrt((L2 - L1)^2 + (a2 - a1)^2 + (b2 - b1)^2)

A deltaE of less than 1 is generally imperceptible. A deltaE of 2 to 3 is noticeable upon close inspection. A deltaE of more than 5 is clearly different.

What "Perceptually Uniform" Means for a Colormap

A colormap is perceptually uniform if equal steps in data value correspond to equal deltaE steps in CIE LAB space. In other words, going from data value 0.1 to 0.2 produces the same perceived color change as going from 0.5 to 0.6.

viridis achieves this. The rainbow (jet) colormap does not — its deltaE per data step varies wildly across the range, with large jumps at some transitions (yellow to green) and small jumps at others (blue to cyan).

Later, in Part III, we will use the colorspacious Python library to compute LAB coordinates and deltaE values for any colormap, giving you the mathematical tools to verify perceptual uniformity yourself. For now, the key insight is: perceptual uniformity is not a subjective aesthetic judgment. It is a measurable, quantifiable property of a colormap, grounded in a formal model of human color perception.


Chapter 3 complete. Proceed to the Exercises, Quiz, or Case Studies.