Colormap engineering to highlight small values

38 views (last 30 days)
I would like to construct a colormap for a set of data where the values range from [0,100] but I want the values in the [0,20] range to be more noticeable as they get to zero. Ideally lightness would be similar across the range but chroma would increase sharply toward zero so you could see the differences in the [0,20] range. Here is what I tried so far, but the decreased lightness toward zero makes it hard to see. Any suggestions? It seems like having color relate on a log not linear scale to the values might help.
figure;
% Make fake dataset
z = peaks;
z = z - min(z(:)); % Make 0 the smallest value
z = z*100/max(z(:)); % Make 100 the largest value
[nRow, nCol] = size(z);
surf(1:nRow, 1:nCol, z); % Make a color-coded 3D plot
colormap(flipud(copper)); % Colormap that should highlight the lowest values
  1 Comment
Adam
Adam on 2 Nov 2018
If you want to highlight small subsets of the range you may want to specify a larger colourmap size, in addition to choosing a custom colourmap as Stephen suggests below, to ensure there are enough actual colours on the map to give the variation within only 20% of the full range. It may be that ~51 as you would get by default with a size 256 colourmap is enough, but it may not with a colourmap specifically designed for this purpose.

Sign in to comment.

Accepted Answer

Steven Lord
Steven Lord on 2 Nov 2018
Since you're calling surf, consider calling it with four inputs (the fourth, C, being the color data for the surface) and setting the CDataMapping property of the surface to 'direct'. You could generate C using discretize on your data to bin the data, with smaller bins for ranges where your data contains smaller values and larger bins where it contains larger values.
Depending on your application one of the others (like gray, bone, or pink) may be a better choice than a flipped copper colormap. See the pictures on the colormap documentation page. If none of these look right for your application, you could start with one that's relatively close and tweak it with the Colormap Editor by adding, removing, moving, or editing the color markers.
  3 Comments
Stephen23
Stephen23 on 5 Nov 2018
@KAE: yes. That is why I gave you a link to my CubeHelix colormap generator.
KAE
KAE on 5 Nov 2018
Edited: KAE on 5 Nov 2018
Here is what ended up working for my particular application (I used makeColorMap.m). To highlight variation in the 0-20 range, I sacrificed the ability to show any variation in the 20-100 range. (Sorry I discovered this would work for my data after asking the question.)
% Go from red to black for values within 0-20
cMap = makeColorMap([1 0 0], [0 0 0], 20);
% Only use black for any value between 20-100
cMap = [cMap; zeros(100-length(cMap), 3)];

Sign in to comment.

More Answers (1)

Stephen23
Stephen23 on 2 Nov 2018
Edited: Stephen23 on 2 Nov 2018
You will need to either:
  1. scale the values before plotting (e.g. log/exp), or
  2. create/find a suitable colormap that highlights that region.
Personally I would start with the second option: changing data in order to plot it rather a hack job. My Cubehelix colormap generator might let you create a colormap that suit your needs:
Otherwise see if you can find a nice colormap that does what you want:

Tags

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!