I am trying to make a color bar with discrete colours on the right hand side of a surf() plot, and I can only seem to get a continuous one. Does anyone know how I might go about doing this? This is my current colorbar and corresponding picture. Thanks.
define a sequential discrete color map with first color white.
How do I make the colorbar of my image plot in matlab to get discrete values without only giving colour to parts of my data - Stack Overflow
How to have a discrete color bar for scatter3?
How to make a discrete colorbar with specified intervals?
The only way I managed to find to stop this is to re-colour each section of the colour bar in Inkscape with the discrete colour that was meant to be in that section. In reality, I think this just inserted another rectangle of that colour within that box, but it worked ok. This wouldn't work if my tickmarks didn't completely separate each section of the colourbar though.
Not a pretty solution, but it worked for me!
This is an issue to do with how Inkscape exports bitmaps, discussed here. The solution is to open the offending pdf file (the one output by Inkscape) in a text editor, find the line(s)
/Interpolate true
and replace it/them with
/Interpolate false
Will had a great idea to use histc(), but I had to edit his code to make it work for me. Here's what I ended up with.
my_colormap = [204 204 204
153 153 153
255 255 178
254 204 92
253 141 60
240 59 32
189 0 38
0 0 0]/255 ;
binEdges = [0 0.001 0.005 0.01 0.05 0.1 0.25 0.5 1] ;
labels = textscan(num2str(binEdges*100),'%s') ;
labels = labels{1} ;
labels{length(labels)} = [labels{length(labels)} '%'] ;
[~,indices] = histc(map_data,binEdges);
indices(isnan(map_data)) = NaN ;
indices(isinf(map_data)) = NaN ;
figure ;
pcolor(indices-1) % Instead of image(), to display NaN values as white
shading flat
axis equal tight
colormap(gca,my_colormap); % gca as first argument prevents
% colormap from changing for all
% subsequent plots
h = colorbar;
caxis([0 length(binEdges)-1])
h.YTickLabel = labels ;

MATLAB only has built-in support for linear colormaps. Therefore for nonlinear mappings like this one, you need to transform the values of map_data so that the changes in color are evenly spaced. For a discrete colormap like this one, integer indices are ideal, and you can get them easily using histc:
ranges = [0 0.001 0.005 0.01 0.05 0.1 0.25 0.5 1];
[~,ind] = histc(map_data,ranges);
Use the indices in ind in lieu of the values in map_data as your color data, and then all you need is to apply the specified colors as a colormap. Where you need to label the true map_data values on your colorbar, manually relabel the YTickLabel of the corresponding colorbar.
I don't have the mapping toolbox to demonstrate this with geoshow, but displaying as a straightforward image works as follows:
image(ind)
axis equal tight
set(gca,'YDir','normal')
colormap([204 204 204
153 153 153
255 255 178
254 204 92
253 141 60
240 59 32
189 0 38
0 0 0]/255);
h = colorbar;
h.YTickLabel = edges(h.YTick)*100;
Which results in the following:

