3

In MATLAB, I have a matrix map_data associated with referencing object R (both in this MAT-file). I want to map it with a discrete colorbar given an irregular range of values to look something like this:

enter image description here

I would like to use geoshow() or something similar that allows me to reproject at will and to overlay shapefiles on top of the raster. But really anything that gets me on the right track would be much appreciated.

I'm using MATLAB r2014b. Here is the relevant information for the colormap:

                                R    G    B
0     <= map_data < 0.001     204  204  204
0.001 <= map_data < 0.005     153  153  153
0.005 <= map_data < 0.01      255  255  178
0.01  <= map_data < 0.05      254  204   92
0.05  <= map_data < 0.1       253  141   60
0.1   <= map_data < 0.25      240   59   32
0.25  <= map_data < 0.5       189    0   38
0.5   <= map_data < 1           0    0    0

Cross-posted at MATLAB answers.

Adriaan
  • 17,741
  • 7
  • 42
  • 75
Sam R
  • 172
  • 11

2 Answers2

1

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:

map_data with discrete colormap

Will
  • 1,835
  • 10
  • 21
  • Ah, great suggestion! It requires a bit of editing to make it play nice for me though, so I'm not going to "Mark as answer." I'll put my code in a new answer, and if you want to incorporate that into yours I'll mark yours as the answer. (Pending someone telling me how to use a mapping toolbox function, that is.) – Sam R Jan 12 '16 at 16:21
  • (And I don't yet have the SO reputation to upvote :-/) – Sam R Jan 12 '16 at 16:31
  • Please help me with a similar query but needing output in mollweid projection: http://stackoverflow.com/questions/39155845/attaching-customized-colormap-to-geoshow-in-matlab – Munish Aug 25 '16 at 22:43
1

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 ;

Resulting plot

Community
  • 1
  • 1
Sam R
  • 172
  • 11