Color Scale for Vote Results Maps
Painters are masters of colors. Claude Monet did 250 different paintings of water lilies, adapting just his color palette to reflect the changes in lighting due to weather conditions, season and time of the day. Photographers also often play with colors to generate certain emotions or atmospheres, even in popular shows like House of Cards. But there's not just an 'eye for color', there's also some scientific evidence about what makes a color palette good or not for a certain purpose.
The proper use of colors in data visualization is a research topic on its own. Several scholars have studied how we perceive colors (e.g. the publications by Bernice Rogowitz or Theresa-Marie Rhyne). Yet many data visualizations on the web are careless about colors.
The topic is vast. In this post, I will just discuss the issue of color scales for representing "yes-no" vote results in an undistorted way in choropleth maps.
Many naive maps displaying yes-no vote results just represent regions in vivid green or red, based on the majority of yes or no.
In the western culture at least, greens and reds are strongly connoted with yes and no. However, there are at least two problems with the way they are typically used on maps:
- Nuances: Proportion of yes and no is not visible
- Colorblindness: Colorblind people usually cannot tell the difference between green and red
Let's address those two issues.
Nuances in vote results can be shown by applying linear scales to reds and greens. For example, one might say that a "lighter" green means a yes closer to the 50% threshold, while a "darker" green leans towards 100% of yes.
Nevertheless, our perception of colors is not linear, our eye being much more sensitive to green. Therefore, for the visualization to be truthful, the shades must be chosen so that their luminance on both sides of the spectrum is similar (70% yes should have the same luminance as 70% red, with just the hue changing). We can approximate the luminance of colors by converting them to grayscale (it's actually a bit more complicated than that).
Also, recent research argues that that the central point, the 50-50 point, should be in a non-confusing color, so that a given change in data is reflected in the visualization in a way that let us perceive it correctly (in other words, a change in the data should be shown as a perceptually equivalent change in the visualization). This kind of scale is called a diverging scale: there is a central point in a neutral color, and the colors diverge from this central point by having different hues on each side. For example:
However, this works well only if the data is not too close to a 50-50 result. Otherwise, in the example above, telling if a county is more blue-ish or red-ish becomes challenging. We see it for a few counties in the image above. Let's cheat with the data to highlight the effect:
Our visual perception is good at certain things. Distinguishing between close shades of a color is not one of them. Therefore, when the results of the vote in a region is slightly higher or lower than 50%, it should be clearly visible from the color that the results leans towards blue (democrat) or red (republicans) in the Virginia example, or towards green (yes) or red (no) in yes-no vote maps. This is not the case in the previously proposed solution. Let's keep that in mind for later and move on to our next issue.
Up to 10% of people are colorblind. Let's have another look at our previous example, through the eyes of a person affected with Deuteranopia, a common form of color deficit.
Not great, right? It's indeed impossible for colorblind people to distinguish the shades of red and green used in that map. Fortunately, colorblindness has been well studied. There are even mathematical formulas to convert colors in order to estimate what colorblind people see. Based on that research, many have proposed color scales that are safe to use for colorblind people. A famous researcher in the field is Cynthia Brewer who created a tool to help you select color scales, including colorblind safe ones. Brewer's colorblind safe swatches to replace green and red were summarized by Andy Kirk, another famous data visualisation guy, here and there:
This is great. But it's just pairs of colors, there's no nuance, no "scale", to show how much a given value deviates from 50-50 towards "red" or "green". Also, as we said above, the use of red and green is a convention in our culture. It's a pity that the color swatches proposed aren't even close to "true" red an green. We probably can do better. Or at least, try.
A Color Scale for Yes-No Vote Results
In summary, we know that a good color scale for yes-no vote results should be nuanced (to encode proportion of yes or no) with comparable luminance on both sides of the scale, have colors that are clearly distinguishable even when close to 50-50, and be safe to use for colorblind people. Plus there is another nice-to-have feature: the scale should to be as close as possible to a red-green color scale, because, well, 90% percent of the population is able to see red and green and is used to their cultural meaning.
After patient and perseverant trials, using the great Chroma.js Color Scale Helper by Gregor Aisch, I could come up with what I hope is a decent scale. It is undistorted in terms of luminance, provides nuances, lets you easily perceive the difference between yes and no even close to the 50-50 point, is colorblind-safe, and somewhat respects the red-green convention (come on, turquoise is almost green).
Through the eyes of a colorblind person, the map above looks fine, with the two ends of the scale clearly separated.
Zooming in on the scale itself:
Not too bad, right? Certainly would other colors be more effective for colorblind people alone, but they would somewhat be surprising for non-colorblind, because they would be too far away from the conventional red-green. I think this scale is a good compromise, and it surely improves the situation a lot compared to the first examples I presented in this post.
How to use?
I generated the colors of the scale using these settings on Chroma.js. The two central colors were too close in terms of shades, so I removed them. To apply the color scale on the map, I used a D3 threshold scale configured as follows:
d3.scale.threshold() .range(['#8b0000','#ad4835','#cb7c6a','#e3afa3','#b7d3d3','#87b8b7','#559c9b','#008080']) .domain(d3.range(0.2,0.9,0.1));
You're free to use this color scale for any purpose. It comes without any guarantee though. If you do use it, please send me a short tweet, I'd be delighted to see it was useful to someone!