matlabcolormapcolor-mapping

Matlab colormap & caxis matching nonlinear plots


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


Solution

  • 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:

    enter image description here

    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;