# image/imagesc scaling colors to a specific range

297 views (last 30 days)
owr on 20 Dec 2012
Hi folks,
Im hoping some of you image processing gurus know how to do this with little effort.
I have 2 matrices with similar, but not equivalent, data ranges. Id like to visualize them independently using image/imagesc but use a common color scale so that "red" can be compared to "red". If I use imagesc, each visual uses an independent scale based on the respective matrices' data range.
For example, c1 ranges from 0 to 2:
c1 = 2*rand(5,5);
and c2 ranges from 1 to 3:
c2 = 2*rand(5,5) + 1;
I'd like to graph each independently in different figures but use a common color scale that ranges from 0 to 3.
Thanks!

owr on 20 Dec 2012
Ok - I think I have an answer to my own question.
This seems to be doing the trick:
c1 = 2*rand(5,5);
c2 = 2*rand(5,5) + 1;
figure;
imagesc(c1);
caxis([0 3]);
colorbar;
figure;
imagesc(c2);
caxis([0 3]);
colorbar;

Walter Roberson on 20 Dec 2012
colormap(jet(128)); %set colormap choice and colormap size as appropriate, not more than 256
minV = min(min(c1(:)), min(c2(:)));
maxV = max(max(c1(:)), max(c2(:)));
rangeV = maxV - minV;
thismap = colormap();
maxcol = size(thismap, 1) - 1;;
c1s = uint8(floor((c1 - minV) ./ rangeV .* maxcol));
c2s = uint8(floor((c2 - minV) ./ rangeV .* maxcol));
f1 = figure();
ax1 = axes('Parent', f1);
image(c1s, 'Parent', ax1);
colormap(f1, thismap);
f2 = figure();
ax2 = axes('Parent', f2);
image(c2s, 'Parent', ax2);
colormap(f2, thismap);
Setting the colormap before creating a figure is not strictly necessary; it just makes the code easier to follow. The number of entries in the colormap needs to be known when c1s and c2s are being calculated, but the colormap content itself is not needed at that point. And the scaling can be postponed until after the first figure is created. Just makes it a bit harder to read the code.
owr on 20 Dec 2012
Walter, thank you very much for taking the time to put together this example. I appreciate your efforts.
Im going to leave this open for a bit longer becasue this is still not exactly what I need. Also, Im a bit suprised their isnt a simpler way to do this that doesnt involve mapping c1 and c2 to indicies into the associated colormap.
The issue with this current solution is that when you add a colorbar, the tick values on the colorbar now range between the min and max range of c1s and c2s, not the orignal range of the data c1 and c2. For example, if you run the code below you'll see that colormap ranges from 0 to 127 (the number of colors in the map) vs. 0-3 (the expected range of the original data).
Im suprised there's not a simple property name/value pair that can be passed to "image" that defines [0,3] to be the range you want the colormap to scale to. Am I missing something?
Code example:
% Define data
c1 = 2*rand(5,5);
c2 = 2*rand(5,5) + 1;
% Define color map - scale c1, c2 data
colormap(jet(128)); %set colormap choice and colormap size as appropriate, not more than 256
minV = 0; % min(min(c1(:)), min(c2(:)));
maxV = 3; % max(max(c1(:)), max(c2(:)));
rangeV = maxV - minV;
thismap = colormap();
maxcol = size(thismap, 1) - 1;
c1s = uint8(floor((c1 - minV) ./ rangeV .* maxcol));
c2s = uint8(floor((c2 - minV) ./ rangeV .* maxcol));
% Create figures/images
f1 = figure();
ax1 = axes('Parent', f1);
image(c1s, 'Parent', ax1);
colormap(f1, thismap);
colorbar;
f2 = figure();
ax2 = axes('Parent', f2);
image(c2s, 'Parent', ax2);
colormap(f2, thismap);
colorbar;