# A good divergent color palette for Matlab

#### INTRODUCTION

Before starting my series on perceptual color palettes I thought it was worth mentioning an excellent function I found some time ago on the Matlab File Exchange. The function is called Light and Bartlein Color Maps. It was a Matlab Pick of the week, and it can be used to create four color palettes discussed in the EOS paper by Light and Bartlein. Each of these palettes is suited for a specific task, and the authors claim they are non confusing for viewers with color vision deficiencies.

In the remainder of this post I will showcase one of the palettes, called orange-white-purple, as it is good divergent scheme [1]. With the code below I am going to load the World Topography Matlab demo data, create  the palette and use it to display the data.

```%% load World Topography Matlab demo

%% create Light Bartlein orange-white-purple diverging scheme
LB=flipud(lbmap(256,'BrownBlue')); % flip it so blue is for negative(ocean)
% and green for positive (land)

%% plot map
fig2 = figure;
imagesc(flipud(topo));
axis equal
axis tight
axis off
set(fig2,'Position',[720 400 980 580]);
title(' Non-symmetric divergent orange-white-purple palette','Color',...
'k','FontSize',12,'FontWeight','demi');
colormap(LB);
colorbar;```

And here is the result below. I like this color scheme better than many othera for divergent data. One only issue in the figure, although not inherently due to the palette itself [2], is that the centre of the palette is not at the zero. This is a problem since the zero is such an important element in ratio data, in this case representing sea level.

#### MAKING THE PALETTE SYMMETRIC AROUND THE ZERO

The problem fortunately can be easily fixed by clipping the data limit to a symmetric range. In Matlab this has to be done programmatically, and rather than going about it with trial and error I like to do it automatically with the code below:

```%% establish anchor to centre colormap midpoint at zero value
% calculate the difference between the signed most negative and most
% positive values in  data and use both the numerical result and its sign
% to assign the colormap automatically. This will anchor the midpoint
% to the zero in the data.
M=abs(max(max(topo)));
m=abs(min(min(topo)));
if M-m>=0
clim=[-m m];
else
clim=[-M M];
end

%% plot new map and compare
fig3 = figure;
imagesc(flipud(topo),[clim]);
axis equal
axis tight
axis off
set(fig3,'Position',[720 400 980 580]);
title('Symmetric divergent orange-white-purple palette','Color','k',...
'FontSize',12,'FontWeight','demi');
colormap(LB);
colorbar;```

And here is the result; now it looks perfect.

#### COLOR VISION DEFICIENCY SIMULATIONS

To test the claim that this color palette is not confusing for viewers with color vision deficiency I run three simulation using the Vischeck plugin for ImageJ (see the related contents section for more details, and also check the Color Blind Essentials ebook) to show how viewers with Protanopia, Deuteranopia, and Tritanopia would see the map above. Here they are, and I think they passed the test. Let me know what you think.

#### FOOTNOTES

[1] I do indeed recommend it for geoscience ratio data;  I also do suggest it it for seismic data as a better alternative to the similar red-white-blue because the colors in the latter are more confusing. However,  neither is optimal because of the white at the low amplitude values. I’d recommend a neutral gray. But that’s another story, which I will tell at the end of my series on color palettes.

[2]  The issue arises from the fact that the data limits are not symmetric, with most negative extreme (lowest areas of the ocean floor) being higher in absolute value than the most positive extreme (highest areas on land). Notice that the demo data were clipped to begin with.

#### RELATED POSTS (MyCarta)

A rainbow for everyone

Better Palettes

Is Indigo really a colour of the rainbow?

The rainbow is dead…long live the rainbow! – Part 1

The rainbow is dead…long live the rainbow! – Part 2: a rainbow puzzle

Why is the hue circle circular at all?

#### RELATED CONTENT (External)

Color Blind Essentials eBook

Vischeck

Vischeck simulations using ImageJ plugin

Vischeck simulations online

## 16 thoughts on “A good divergent color palette for Matlab”

1. Aesthetically, I agree that the colors employed in the LB colormap are indeed quite pleasing, but its not suitable for accurately displaying land/sea boundary. Note the visually flat and undifferentiated expanse of reddish-white one either side of 0. This will obscure the sharp land/sea boundary. The default colormap generated by mapping toolbox function demcmap (available in R2012a) has a sharp break in color continuity at ~0 ( cyan(sea) | green(land) ) which results in a corresponding sharp delineation of the land/sea boundary in the map.

• Hi Harold
Thanks for your feedback. The main point of my post was more to confirm this LB divergent palette is safe for all viewers, whether trichromats or dichromats.
As for demcmap, I like the general idea. I cannot see it in action as I’m still working with an older version of Matlab, but I was able to look at the documentation
http://www.mathworks.com/help/toolbox/map/ref/demcmap.html
I see that the function selects automatically a number of land and sea colors proportionally to the range of positive and negative values in the data. This is really a great feature. It’d be great to use it in the future.
However, I’d disagree at least in part with what you say about the land-sea boundary.
From the physical point of view, looking for example at a map like this
or at an elevation profile, there’s nothing inherently sharp about the transition form land to ocean. The real gradient break is the transition from continental shelf to slope, which can be seen as a sharp break in the map above.
The flatness you refer to is inherent with the data, with both the shelf and the portion of the continents above and around sea level being rather dull. In that way the LB color palette is true to the data.
We could improve on the result using a color palette that has a double gradational scheme (two colors on each side of the zero), which would allow better contrast and visual resolution of the continental areas.
I agree that in some context having a clear indication of the coastline may be an important map feature, so it would be good to artificially enhance it.
Using a color palette like the one recommended by researchers at IBM visualization centre, for example in Figure 1 below here, would allow both, because there is a sharp break, but it still honours the data structure, as each half of the palette is perceptual, whereas the examples in the demcmap do not have this property.
http://www.research.ibm.com/people/l/lloydt/color/color.HTM

2. Matteo, nice post, and I like how you are extending this out of something that went mainstream. Question for you. Is there ever a time or a place where non-linear ramps or non-linear gradients are useful? Any suggestion? Say you want to portray a lot of detail around sea level, but you still want colors to span the full range of elevation (not clipped). I have deliberately made funky non-linear spectra across the range (Petrel’s colorbar editor lets you do this with a dragable bar), to show subtleties in structure near a proposed water contact say, or near the crest of a structure. You might say it’s the enemy or antithesis to the perceptually balanced color map. Should I be slapped? What are your thoughts?

• Hi Evan

For me using a perceptual palette is important for our first look at data or maps, so that we do not condition our brain to see edges where there are not, because then it is difficoult to step back. When I first scan through a seismic volume, for example, I want to look at ‘unadulterated’ data – so to speak. But there is nothing wrong I think with using nonlinear profiles in a later stage when doing detailed work. Again for seismic data, Alistair Brown rightly points out that seismic interpreters spend most of their time interpreting intermediate amplitudes, so why not stretch or enhance the range of colors available for those? The problem I have is when we just apply abrupt gradient changes to the palette’s lightness profile. I do like Petrel’s nonlinear option or even Seisware’s stretch and squeeze, but often find it hard to replicate from volume to volume a palette I like, particularly with Petrel. Perhaps a possibility would be to create a whole set of color palettes with cube law profiles, using different exponents, and load them all up. For your sea level example you could use one like this:
http://mycarta.files.wordpress.com/2012/10/cube_law.jpg
which uses a large portion of the available lightness range close to zero elevation, with a mirror cube law for elevations below sea level. Of course this takes some programming background work. What do you think?

• PS you may want L* decreasing exponentially from 100 to 0 as elevation increases, so as to have lighter colors around sea level.

3. You have made a good point about all of this. Funky non-linear colour gradients can be very un-reproducible, and not easily transferable to another surface or object. Extremely ad hoc, perhaps to a fault. The function you have given an example seems like a good candidate. Next time I have a map worth colouring I will take this stuff into consideration, and I will try to share it if I can.

Another topic. I was looking at a student’s quick and dirty contour map that they made by “create surface” in Petrel. It was full of weird triangulation artifacts like there was not enough data point or data was too sparse. I wonder if there is a colour scale that can be adopted as a QC tool. Something that would highlight different attitudes (azimuths) where fast gradients in color would be considered areas of gridding artifacts. Colour is our friend, no doubt.

Finally thanks for posting that link on twitter about the IBM research article. Should be essentially reading for anyone who uses a computer 🙂 Can we work on a related article for geophysics? Comb your mental archives for examples.

• Evan

To create those cube law palettes in Matlab you could use the code below, which will give you the L for HSL, L for CIELab, or V for HSV.

l1=linspace(1,power(100,1/3),256);
L1=(power(l1,3))’;
plot(L1,[1:1:256]);
hold on

l2=linspace(1,power(100,0.42),256);
L2=(power(l2,1/0.42))’;
plot(L2,[1:1:256],’r’);

The 1/3 and 0.42 exponents are discussed in this Wikipedia article:
http://en.wikipedia.org/wiki/Lightness

On your QC question: that’s a very interesting topic, although it would be nice to see an example of the artifacts.

I do have some ideas for a paper, I’ll respond via email.

4. Pingback: Comparing color palettes | MyCarta