This is a transcript of a talk I gave at nz.js(c0n); 2017.
Kia ora, I’m Nat. I’m Head of Design for Figure.NZ. We’re a charity, and our mission is to help New Zealand become a data-literate democracy where everyone can use numbers in their thinking.
So, unsurprisingly, I think data visualisation is kind of important. Data viz is all about communicating stories held in numbers and helping people understand the questions to ask.
Can you tell, at a glance, what meaning is in this data? Are there any trends you should pay attention to? Any outliers or spikes or troughs?
Converting it to visual form helps us to immediately see what’s going on. It’s way more user-friendly than the tabular data. The same applies for maps.
In map form, we can quickly see how the data is distributed.
Dataviz is awesome. It makes people happy. It helps to communicate the meaning held in data.
But dataviz that doesn’t include everyone is not so awesome
There’s heaps of stuff that might mean you can’t read a data visualisation, but there are some that we cause by how we design them.
Yeah, I’m talking about accessibility.
We put dataviz into our apps and sites because we want to make communicating information clearer, so I’m gonna go ahead and say we should actually try and deliver on that for everyone.
Excluding people from participating because of the way we choose to communicate information is not only unfair, it’s just plain bad business. We’re a service industry, so we need to serve and empower our users.
The key thing we’re striving for when we’re making accessible visualisation is that the insight should be communicated to anyone, regardless of ability.
Data viz creators mess this up in loads of ways; no alt text, data not being keyboard navigable, or there being no alternate way to see the data. More complex visualisation can also be much harder for less educated people or those with cognitive impairment, even though we enjoy making it more and find it more interesting.
Most of us suck at all of these, but we’ve only got 30 minutes so let’s talk about colour-blindness.
You probably think about this when I talk about colourblindness.
It’s part of the Ishihara plate test — you probably did this as a kid. What it’s measuring is colour vision deficiency. Despite the name, most colourblindness isn’t actually inability to see all colour. The test checks to see if you have decreased ability to perceive differences between colours.
Colourblindness is almost always. inherited, and it’s linked to the X chromosome. This means it’s more common in people who have XY chromosomes than people who are XX.
There’s also a whole bunch of forms — not just the red-green you might’ve heard of.
Eyes work using sensors called rods and cones. The rods sense movement and brightness. The cones in our eyes sense colour — they respond to short, medium, and long wavelength light.
There are 8 different types of colour-blindness.
Anomalous Trichromats have reduced sensitivity because the reception of one of these pigments is misaligned. Most colourblind people will be anomalous trichromats. This means they don’t have complete loss of ability, but it is significantly reduced.
If the cone type doesn’t work at all, you get a form of colour blindness call dichromacy.
There’s also partial or full monochromacy, which occurs when 2 of the cone types are either partially or fully non-functional, and rod monochromacy, when all 3 don’t function.
So how much of a big deal is this? The amount of people impacted depends on ethnicity and gametes. It’s most common in Europeans with XY chromosomes, including Pakeha, with somewhere between 6–9% of people affected. People of asian descent clock in at 5–7%, and Māori, Pacific, African, and South American XY carriers are 1–3%. XX carriers are less than 1% everywhere.
This makes it a rare bird in accessibility terms. It disproportionately impacts people who form part of the tech community. This almost certainly impacts members of your team. If you can’t motivate people to solve wider accessibility issues, at least you should be able to motivate them to start with this!
So what’s the problem with this and dataviz? Turns out that in dataviz, we rely on colour a lot to communicate meaning.
Let me show you a chart from the old Figure.NZ website. This is in all the forms of colourblindness. This was before we added a requirement for charts to be colour blind accessible.
It’s…not great. Here’s how it looked for deuteranopes — that’s the 5% one.
And partial monochromacy, which may seem less important when you look at the stats — it’s less than .1 of a % of people, but it is similar to how it appears for older adults with low contrast vision.
And yeah, that’s already a problem, and it’s going to become a bigger one.
So, what that all means is if we get this wrong, quite a lot of people aren’t going to be able to read the wonderful things we’re taking the time to create. Let’s do it right, then.
There’s 2 basic principles at play here:
1. Choose better colours.
2. Reduce your reliance on colour as the sole method of communication
Let’s talk colour. There’s obviously more to colour than accessibility. We want visually appealing colours that communicate information in an ambiguous and unbiased way. Well, I want unbiased, if you want biased, that’s your call I guess. We also want them to be able to be distinguished.
We want as much perceptual contrast between colours as possible, regardless of vision type. Perceptual contrast comes from difference in hue and in brightness or luminosity. The basic idea is that when your vision messes with hue, the variation in luminosity means you can still see what’s going on.
So, most people’s instinct is to start with colours that they think are visually distinctive. The classic example is the rainbow palette.
You do need to know a little bit about colourspaces, though, so let’s talk nerdy. A colourspace is a mathematical representation of colours. Not all colourspaces perfectly match what we can see.
Most of us work using either hex codes or RGB values. They’re representations of the same RGB colourspace.
This is a cartesian coordinate based system (basically, you get 3 values that tell you which direction to go in along 3 axes to find the colour.)
But RGB doesn’t map to how we think about colour perception, and this makes it hard to use it to mathematically calculate good contrast palettes.
Like, it really doesn’t. Take a guess and see if you can figure out what the RGB for a colour 10% lighter than this.
Yeah. And if I want to pick a colour either side of that that are visually and perceptively distinct?
RGB blows for this. So what else can we use? Browsers also support another colourspace.
HSL, which is short for Hue, Saturation, Lightness/luminosity.
HSL is a cylindrical coordinate system. You also get 3 values
Saturation runs 0–100 from grey to fully saturation.
Lightness runs 0–100 from black to white.
And hue is allocated along a spectrum from 0–360.
The Red primary is 0 (and also 360) because we’re going around in a circle.
The green primary is 120 degrees.
The blue primary is 240 degrees.
Let’s compare this to RGB.
So, here’s our value. And if we want one 10% lighter?
You just adjust the lightness value.
Seems great, right? A predictable colourspace where we can apply simple math and get a result we expect?
Except for one thing. HSL doesn’t take into account perceptual brightness of hue.
These colours all have 100% saturation and 50% lightness — The only thing that varies is the hue; they are a perfect 60 degrees apart in hue separation. You’d think this means they look the same in monochrome.
But when you look at them in monochrome, not so much. They’re not perceptually equal.
This means using math to make colourblind friendly palettes doesn’t work so well.
So where does that leave us?
Browsers don’t support any other colour spaces.
Some folks at the CIE, which has a long French name I’ll say wrong but translates to International Commission on Illumination decided to standardise colourspaces.
They came up with the CIE L*a*b* colourspace. It includes all the colours we can perceive, and it’s not linked to a specific type of device (so it’s useful for other stuff like converting from RGB to CMYK)
Quick primer: it’s also a cartesian plane system like RGB is, but it’s based on something called opponent colours theory. That basically says that a colour cannot be both green and red at the same time, or yellow and blue at the same time, so we can use a single value for each of these colour pairs. These run on an a and b axis, and there’s a vertical axis for luminance.
This is a weird looking space. It’s not mapped nicely to a cone or sphere or cube, and it’s hard to imagine because it’s different at all 101 available levels of luminosity.
I bet you never thought colour was this complicated.
BUT, the L*A*B* space solves our perceptual brightness problem. These colours all have the same lightness and same saturation (or chroma), but this time, when we convert them into greyscale, they’re identical.
The colours on the slide obviously aren’t a good colour scale to use for viz because we want to have variation in lightness!
LAB is awesome. Computers can use it to calculate colour palettes no problem, but it’s hard to use at a human level because it’s another cartesian coordinate based system. The UX is bad.
Meet L*C*Hº. Don’t worry, this is the last space. LCH is the more friendly cousin of LAB.
LCH takes the LAB space and turns it into a cylinder which keeps the perceptual uniformity. This means it’s like HSL in that we have hue represented by degrees, chroma as the radius from the grey centre, and lightness on the same vertical axis. The coordinates themselves are transformed with some basic trig. But unlike HSL, we don’t have that annoying uneven lightness problem.
This finally gives us a colourspace with a nice UX that we can use to obtain spectrums.
There’s no direct browser support. You can’t just plug LAB or LCH colours into your code.
Enter my good friend: Chroma.js
Chroma.js is going to become your buddy for working with dataviz.
An excellent dev took all of the complexity and packaged it up into one (tiny, 12kb) library. It does a lot of colour analysis and conversion, but what we really care about for this is that it can do interpolations in the LAB and LCH colourspaces and give you RGB or hex values at the end of it.
There’s even a plugin for D3, so you can use it directly when you’re making your data viz. By the way, if you’re not using D3 already, you should just accept our Lord and Saviour into your life. Don’t be tempted to roll your own. It can be a bit scary to start with, but long-term, it’s worth it.
You can interpolate colour scales between two hex codes or named colour values. You can then specify how many color swatches you need. It automatically makes sure that the lightness varies evenly.
You’re probably wondering why I told you about colourspaces and colourblindness when all you need is a bit of JS. If you don’t understand the basics, this won’t work so well for you. You still need to know not to seed it with hues of similar lightness, or to pick red and green.
You can also change the mode to use the LAB space but the result will be a bit less vibrant, although that might be your jam. It can also get a bit better contrast.
If you’re not into the palettes you’re getting, you can also create multi-colour scales using bezier interpolation (which is a fancy way to say smooth curves between points) and lightness correction to make sure that the colours stay equidistant in luminosity. You can use these to force the scale to go through another colour.
The bezier interpolations only run in the LAB space, so, again, less vibrant colours.
Word of warning:
Chroma scales will help to give you palettes that are visually appealing, especially if you follow basic colour theory and use seed colours that occur in nature — sunsets, birds, flowers — that type of thing.
BUT: Because they’re a lightness scale, they’re not the maximum distribution across the space possible for both lightness AND hue. For most ranges, if you have more than 5 colours, you’ll start struggling with perceivable differences.
First step is always to see if you can simplify what you’re trying to communicate. More than 5 lines or bars often means you’re making something too complex. But if you’re really stuck, or if this is all sounding too hard…
Colorbrewer is your friend. Colorbrewer is a series of palettes designed by Cynthia Brewer for use in maps, but they also work well for other types of dataviz.
Colorbrewer does all the hard work for you, and you can even use the chroma.js library to grab the colour palettes and use them in your viz.
I’m not going to get into it here, but there’s also some basic principles about which style of colour scheme you should use for the type of data you’re trying to display — sequential, diverging, or qualitative. This is especially important for maps — you can get away with a bit more in chart form.
So this is what my work ended up with for all forms of colour blindness.
So, if we’ve got colour nailed, what are the other things?
Line charts are really the ones this is hardest for.
First up, be smart about your legend labels. Having a separate legend means you rely on colour to transmit the meaning. Labelling the lines directly removes this requirement, and also reduces the cognitive load for all users by removing a layer of abstraction.
Otherwise, make sure your legend order is the same as the order of your lines at whichever end it’s located.
You can also use interactivity to help by highlighting specific points. The ability to directly interact with a line and see the corresponding labels again removes reliance on colour alone.
This interactive from NZ Herald enables you to mouse-over and select points to examine. Of course, this isn’t very keyboard friendly, so has other accessibility challenges, and increases cognitive load if you want to compare multiple lines against one another as you have to remember which labels map to which lines.
If you don’t have too many lines on a chart (although obviously more than one), you can use different line styles so that the form of the line communicates meaning as well as the colour.
This is built into D3 by default, which is what this snippet is here.
This won’t be suitable if the line has sharp peaks and troughs as it interferes with the readability of the data, but for simpler shapes without too many lines, it can work well. The same applies for point markers of different shapes — if it’s a simple dataset, you can use add a visible point for each data point and make them different shapes for each line.
Perhaps most importantly, don’t leave this up to chance. Test things.
Check if any of your colleagues are colourblind. There’s also a number of apps to emulate each state — I use Sim Daltonism and the Spectrum Chrome plugin.
Many colourblind users will also use Chrome’s High Contrast plugin, so check your viz with that enabled too.
What I want you to take away from this is two things:
- Do visualisations. They are excellent and fun and useful and really can help people understand and ask better questions, but
- Do inclusive visualisations. Once you understand the science, it’s easy to make visualisations that are inclusive of colour blind people. So do it!
🌏 📊 Around the world in 80 shades: Building color blind accessible dataviz 📊🌏 was originally published in Towards Data Science on Medium, where people are continuing the conversation by highlighting and responding to this story.