Search code examples
matlabcolorbar

Change Matlab colorbars' color interval manually


Using three colors, and values ranging from 0-100, Colorbar is per default splitting up the colors at, respectively, 1/3 and 2/3:

enter image description here

I would like to select this interval manually. E.g. at 1/4 and 1/2.

MWE:

clc; close all; clear all

data = (50+50)*rand(10,3)

% green if acc(:,1)<Crit1
% red if acc(:,1)>Crit2
% yellow if acc(:,1)>Crit1 && acc(:,1)<Crit2

Crit1 = 25; 
Crit2 = 50; 

imagesc(data)
mycolormap = [0 1 0; 1 1 0; 1 0 0];
colormap(mycolormap)
colorbar

I have previously posted this question (https://math.stackexchange.com/posts/3472347/), probably in the wrong forum, without any response.


Solution

  • By default, imagesc scales the data and chooses the thresholds betwen uniformly. To change that, you have several options:

    1. Define a colormap with repeated colors that produces the correspondence that you want. To get 1/4 and 1/2 you would need

      mycolormap = [0 1 0; 1 1 0; 1 0 0; 1 0 0];
      

      This gives unequal lenghts in the colorbar, according to the separation between values:

    enter image description here

    1. Apply the thresholds manually, and then change the colorbar labels:

      data = 100*rand(10,3);
      thresholds = [0 1/4 1/2 1]; % thresholds for normalized data
      mycolormap = [0 1 0; 1 1 0; 1 0 0]; % colormap with numel(threholds)-1 rows
      m = min(data(:)); % min of data
      data_normalized = data-min(data(:));
      r = max(data_normalized(:)); % range of data
      data_normalized = data_normalized./r;
      t = sum(bsxfun(@ge, data_normalized, reshape(thresholds, 1, 1, [])), 3);
      imagesc(t)
      colormap(mycolormap)
      h = colorbar;
      set(h, 'Ticks', 1:numel(thresholds))
      set(h, 'Ticklabels', m+r*thresholds)
      

      This gives equal lenghts in the colorbar, so the indicated values do not form a uniform scale. Thresholds are relative to the range of the data.

    enter image description here

    1. Same as above but with absolute thresholds:

      data = 100*rand(10,3);
      thresholds = [0 25 50 100]; % absolute thresholds for data
      mycolormap = [0 1 0; 1 1 0; 1 0 0]; % colormap with numel(threholds)-1 rows
      t = sum(bsxfun(@ge, data, reshape(thresholds, 1, 1, [])), 3);
      imagesc(t)
      colormap(mycolormap)
      h = colorbar;
      set(h, 'Ticks', 1+linspace(0, 1, numel(thresholds))*(numel(thresholds)-2))
      set(h, 'Ticklabels', thresholds)