How to Choose Heatmap Colors: A Color Scheme That Shows Differences in Values
A heatmap is a chart that uses changes in color, often from light to dark, to make patterns in a table of numbers easier to scan. It can be useful when many values appear together, but too many unrelated colors or unreadable numbers on dark cells can make the results difficult to interpret. Using a fictional support-request dashboard, this article explains how to use four blue shades for counts across weekdays and time slots, while keeping the exact figures readable.
Use a consistent light-to-dark scale for ordered values
For quantities such as request counts, a sequential color scale is one option: lighter colors represent lower values and darker colors represent higher values. Rather than switching repeatedly from blue to red or another hue, shades from the same family can communicate the single idea of magnitude. Darker does not necessarily mean dangerous, though. A large number of requests is not automatically an error or an emergency.
In this example, divide the counts into four bins (numeric ranges): “0–2,” “3–5,” “6–8,” and “9 or more.” These cutoffs are illustrative, not universal thresholds for support teams. For a real dataset, choose thresholds based on its distribution and the decisions people need to make. When comparing different weeks, keep the same cutoffs instead of automatically recalculating the color scale for each week.
Do not use color as the sole representation of a value. Keep the actual count in each cell (one square of the table), together with row and column headings for time and weekday. WCAG 2.2 (Web Content Accessibility Guidelines, international guidelines for accessible web content) includes a Use of Color requirement: people must not have to distinguish colors to obtain the information.
Example: four shades for requests by weekday and time slot
Start with a white table surface #FFFFFF and adjust the number text for each colored cell. Each HEX code below is a hexadecimal color value. A contrast ratio describes the difference in relative luminance between text and its background. Under WCAG 2.2 Level AA, normal-sized text generally needs at least 4.5:1 contrast.
- 0–2 requests: Pale blue #EFF6FF with dark navy text #1E3A8A; approximately 9.52:1 contrast.
- 3–5 requests: Medium-light blue #BFDBFE with the same navy text #1E3A8A; approximately 7.29:1.
- 6–8 requests: Stronger blue #60A5FA with near-black navy text #0F172A; approximately 7.02:1.
- 9 or more requests: Deep blue #1D4ED8 with white text #FFFFFF; approximately 6.70:1.
All four text-background pairs exceed 4.5:1. The figures below are fictional, and every time slot covers the same three-hour interval. Wednesday at midday has 11 requests and Friday in the late afternoon has 10, placing both in the darkest bin. The precise values come from the printed numbers, not from the shades alone.
| Time slot | Mon | Tue | Wed | Thu | Fri |
|---|---|---|---|---|---|
| Morning (9–12) | 1 | 4 | 6 | 3 | 0 |
| Midday (12–15) | 5 | 9 | 11 | 7 | 4 |
| Late afternoon (15–18) | 2 | 6 | 8 | No data | 10 |
Place a legend close to the heatmap that explains the numeric range for each shade. For example, the palest blue #EFF6FF and the next blue #BFDBFE have only about 1.31:1 contrast with one another. Do not expect users to identify adjacent numeric ranges just from a small difference between colors; retain both the values in cells and the labeled ranges in the legend.
Distinguish zero from missing data and check interaction states
The Friday morning value of zero means a successful count found no requests. Thursday’s late-afternoon entry, however, represents data that could not be collected, so it is explicitly labeled “No data” rather than zero. Its pale-gray background #F1F5F9 and slate text #475569 have approximately 6.92:1 contrast. Treating a missing value as zero would make it impossible to tell whether demand was low or the measurement was unavailable.
The differences between neighboring shades can be subtle. Even the palest blue #EFF6FF differs from the surrounding white #FFFFFF by only about 1.09:1. Important graphical features and visual indicators for controls generally require at least 3:1 contrast against adjacent colors. Here, the visible numbers, row and column headings, and explicit missing-data label make the content understandable without depending on the shaded boundaries. That does not mean the entire finished interface automatically meets WCAG requirements.
If cells can open more details, make the information available by keyboard and touch as well as mouse hover. For a focus outline—the visible indicator of the item currently ready for keyboard interaction—near-black navy #0F172A can work on the three lighter fills; even on the strongest of those fills #60A5FA its contrast is approximately 7.02:1. On a deep-blue cell #1D4ED8, switching to a white outline #FFFFFF gives approximately 6.70:1. Check the complete outline, including its edges against the surrounding gap, in the real design.
HueRoll lets you select colors by HEX code and check a selected color against white or black. It cannot compare arbitrary pairs of custom colors or automatically determine WCAG AA or AAA passes. The four cell-background and text combinations here were calculated separately. For an effective heatmap, prioritize stable numeric ranges, legible exact values, and a clear distinction between zero and missing data over adding more colors.