Yet Another Way Colormaps Can Be Used to Enhance Your Data Visualization
For most scientists, there is a ton of utility in switching between colormaps. Here I describe a less commonly-used method to get even more from your colormap.
If you’re like me and you learn by reading code, feel free to skip to the end for a code snippet from MATLAB.
When would you want to do this?
You have data you want to display, but most of the values are much smaller than the overall range of values. This can give you the sense that there’s “nothing there” in your image when actually there may be interesting variability that you’re not seeing.
In many cases, people will go to their image adjustment program of choice (ImageJ, Photoshop, etc) and crank up the contrast. This is of course not efficient or good for reproducibility, since people rarely keep track of the exact adjustments they make. And if you have any text on your image, you’ll be adjusting the contrast of that too.
For reproducibility and efficiency, use code for all your data visualization and adjustments (as opposed to manual tweaking in GUIs like ImageJ).
Below I’ll explore two alternative solutions and compare them.
Convert your data to a log scale
This is one approach that is often taken and does not rely on changing your colormap, and it can also help you emphasize variability at the lower end of your data.
There is a lot more visible here, but there are several downsides to this approach. Here are some:
- Not intuitive. Your data is now in log units, which is not intuitive for 99% of people, especially non-scientists.
- Lost values. If your data contains negative values, you will lose these values since negative numbers do not have real logarithms.
- Hard to tweak the amount of contrast you’re gaining. You could do it by changing the base of your logarithm, but who wants to do that?
Make your colormap non-linear
To understand this approach, you first have to de-mystify colormaps. I’m going to explain these concepts using MATLAB but it’s in general true.
A colormap is basically just a list of colors, in the example below, they go from color 1 to color 50. The dimmer objects in your image get assigned lower colors and the brighter objects get higher colors.
Now imagine picking a subset of the colors in a precise way, where you’d want dim objects to range from blue to green to yellow, so you can see the differences in their intensity.
Here’s what you might do with your colormap:
And now if you looked at the same image from above with your new “hand-picked” colormap, it would look more like this:
Am I really going to pick those colors every time I make a figure?
No. That’s what math and code are for!
- Pick a color map — this means a palette and also how many colors it contains (pick a large number — much larger than the number of different objects you want to be able to see — I usually go with 1000).
- Pick a mathematical function (for example, an exponential) and obtain its output values f(x) over a range of x’s large enough to show the behavior you want.
- Rescale the outputs into integers from 1 to the number of colors in your color map.
- Use the rescaled outputs to specify a new colormap that is a subset of the original.
Here is how I would implement this in MATLAB
The code below would easily be adapted to any coding language, the main idea is just reindexing your colormaps using something other than a linear progression.
You can see the result below, with images and colormaps above the function used to reindex the colormap. You’ll notice that the colorbars on the right side are all the same, which is because you have not changed your data — only the way it’s displayed!
The nice thing is that you can get creative and change the shape of the function however you want. You could even use a sine wave if you wanted to!
Please feel free to @ or DM me on Twitter (neurojojo) with any cool images you generate using this approach, or questions you have!