I am trying to fit my data to match the published map below (the figure on the left), but cannot figure out the right code for the colour bar. The increments are non linear.
Here is the relevant code that I have (it is part of a very large code for spatial mapping so unfortunately not possible to make it reproducible):
caxes.donatt = [0 2.5];
colormaps.donat = mf_colormap_cpt('BlWhRe', 8);
colormaps.donat(1:1,:) = [0.00 0.00 0.50];
colormaps.donat(2:2,:) = [0.00 0.50 1.00];
colormaps.donat(3:3,:) = [0.67 0.90 0.93];
colormaps.donat(4:4,:) = [1.00 1.00 1.00];
colormaps.donat(5:5,:) = [1.00 0.87 0.68];
colormaps.donat(6:6,:) = [0.98 0.67 0.38];
colormaps.donat(7:7,:) = [1.00 0.40 0.10];
colormaps.donat(8:8,:) = [1.00 0.00 0.00];
Here is a picture of the expected result of the colorbar: expected result
Here is my current result using the code shown above: current colorbar result
The problem here is that the colormap you're trying to mimic is non-linear, but MATLAB maps the data to a colormap in a linear fashion. You can solve this by first binning your data using histcounts
to create a linear mapping, then adjusting the color bar ticks labels to make your linear colormap appear non-linear. Here's an example:
data = 2.5.*rand(200); % Sample random data in the range [0 2.5]
edges = [0 0.5 0.75 0.9 1.1 1.25 1.5 2 2.5]; % Define edges of nonlinear map
imgMap = [0.00 0.00 0.50; ... % Colormap colors
0.00 0.50 1.00; ...
0.67 0.90 0.93; ...
1.00 1.00 1.00; ...
1.00 0.87 0.68; ...
0.98 0.67 0.38; ...
1.00 0.40 0.10; ...
1.00 0.00 0.00];
[~, ~, bin] = histcounts(data, edges); % Bin the data according to the edges
image(bin); % Plot bin index, not the original data
colormap(imgMap); % Add new colormap
hBar = colorbar; % Add color bar
set(hBar, 'TickLabels', ... % Modify color bar tick labels
[{''}; cellstr(num2str(edges(2:(end-1)).', '%g')); {''}]);
And here's the sample plot:
Note that if your data contains NaN
values, you will get a bin value of 0, which in the above example will be mapped to the lowest value in the colormap range (which is the first element of imgMap
). To reconstitute these NaN
values, do the following after binning the data with histcounts
:
bin(bin == 0) = nan;