How to make a discrete colorbar with specified intervals?

393 views (last 30 days)
Hi all,
I want to change the default colorbar to a discrete one (i.e. with blocks) of non-evenly spaced intervals.
I uploaded an image as an attechment to show what I would like.
I hope someone can help.
Thanks

Answers (2)

Cris LaPierre
Cris LaPierre on 7 Feb 2021
Your colorbar is set by the resolution of your colormap. If you want a colobar with 16 colors, set a colormap that only has 16 defined colors. Here's an example that recreates the "block" colorbar.
contourf(rescale(peaks,0,500))
C=parula(15);
C(end+1,:)=1;
colormap(flipud(C))
colorbar('Ticks',linspace(0,500,17),...
'TickLabels',["" "0.01" "0.5" "1" "1.5" "2" "5" "10" "15" "20" "25" "50" "75" "100" "250" "500" ">500"]);
  6 Comments
Cris LaPierre
Cris LaPierre on 11 Aug 2022
I'm going to create a new answer and unaccept the one that is currently accepted as it is misleading.

Sign in to comment.


Cris LaPierre
Cris LaPierre on 11 Aug 2022
In re-reading the orginal question, it is worth clarifying that this solution only visually creates the colorbar. On its own that is not enough to make the data in the plot match the colorbar. Note that the tick locations are evenly spaced from 0 to 500. The code programmatically replaces the original labels with the new labels.
Separate code is necessary to rescale the values so that the colors in the colorbar correspond to values in the plot. Said another way, anything colored white has a value up to 31.25, not 0.01.
tickVals = linspace(0,500,17)
tickVals = 1×17
0 31.2500 62.5000 93.7500 125.0000 156.2500 187.5000 218.7500 250.0000 281.2500 312.5000 343.7500 375.0000 406.2500 437.5000 468.7500 500.0000
Apologies for that confusion. Here's sample code for how I would do this for my example. To work, you also have to specify the levels contourf should use.
% Create a data set with values from 0 to 600 (was 500 previously)
data = rescale(peaks,0,600);
% copy a copy of the data for rescaling
newdata = data;
% New tick values
newTickVals = [0 0.01 0.5 1 1.5 2 5 10 15 20 25 50 75 100 250 500 inf];
for tv = 2:length(newTickVals)
% find all data between the new tick ranges, one block at a time
ind = data>newTickVals(tv-1) & data<=newTickVals(tv);
% Change the corresponding values in the copied data to scale to the
% block edges
newdata(ind) = rescale(data(ind),tickVals(tv-1),tickVals(tv));
end
% The rest of the code remains the same (with addition of specifying
% levels)
contourf(newdata,tickVals)
C=parula(15);
C(end+1,:)=1;
colormap(flipud(C))
colorbar('Ticks',tickVals,...
'TickLabels',["" "0.01" "0.5" "1" "1.5" "2" "5" "10" "15" "20" "25" "50" "75" "100" "250" "500" ">500"]);
Now the colorbar colors correspond to the values in the original data variable
Note: Because this approach rescales the data to make a non-linear colorbar range possible, I think this approach only works for 2D plots (i.e. plots where only color is used to show the Z value. This approach will distort the appearance of the plot if it is plotted in 3D, e.g. a surface plot.)

Community Treasure Hunt

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

Start Hunting!