1. Background
2. Useful Properties
3. Example 1: Using Two Colormaps in a Single Axes
4. Example 2: Use a Different Colormap in Two Separate Axes
5. Example 3: Use Three Colormaps in a Single Axes
6. Example 4: Use Multiple Colormaps in a Single Figure
7. Example 5: Overlay Multiple Axes with Differing Colormaps in a Single Figure
Background
Each figure has its own colormap, stored in the Colormap property. To view it, you can use the command:
ColorMap = get(gcf,'Colormap')
All the objects which are children of a figure refer to the parent figure's colormap if they need to access one. If you want two or more different objects to use varying colors, however, it is possible to construct a colormap that contains several smaller colormaps concatenated together and force each object to use a different section of the larger colormap corresponding to the small colormap. For example, you can build a colormap that consists of the cool and gray colormaps by doing the following:
cmap = [cool(32); gray(32)];
The first 32 rows of cmap are from the cool colormap, and the last 32 rows are from the gray colormap.
Useful Properties
Three properties that are used to determine the range of colors used to color an object are CData, CLim, and CDataMapping. They are defined below, or you can refer to the Handle Graphics Online Documentation for more in-depth information:
* CData: The CData property contains a matrix that defines the colors at every point in the ZData (YData for 2-D patches). By default, Patch and Surface objects scale their CData into the colormap. The minimum value of the CData is mapped to the first row of the colormap, and the maximum value is mapped to the last row of the colormap. The remaining elements are mapped proportionally to rows in the colormap using the following equation:
m = size(colormap,1);
CData = get(H,'CData')
cmin = min(CData(:));
cmax = max(CData(:));
idx = min(m,round((m-1)*(CData-cmin)/(cmax-cmin))+1);
idx contains integer values that range from 1 to the length of the colormap. The values are the actual row numbers of the colors used in the surface plot.
The CData for an image object defines the rows in the colormap used to color the corresponding pixel (or bin). If the CData is logical, than a value of 0 corresponds to the first row, and a value of 1 to the second row. In this case to use multiple colormaps the CData should be converted to direct indexing; this is demonstrated in Example 2.
* CDataMapping: The CDataMapping property of Patch and Surface objects determines whether the objects scale their CData into the colormap (which is the default behavior) or whether the CData is a direct index into the colormap and should not be scaled.
* CLim: CLim is a property of Axes objects. It is a two-element vector that defines the color range. Usually, the CLim property contains the minimum and maximum values of the CData. You can use the caxis command to change the axes CLim property.
By manipulating these three properties, you can force different objects to use different portions of the colormap. First, scale the CData properties of the individual objects so that they have nonoverlapping, contiguous values and the same range. If the CData values do overlap, then the plots will share some of the same colors. After scaling, set the CLim property so that it contains the minimum and maximum values of all the CData matrices. The following examples illustrate how to use multiple colormaps in single axes and multiple axes.
Example 1: Using Two Colormaps in a Single Axes
colormap([cool(64);gray(64)])
[X,Y,Z] = peaks(30);
h(1) = surf(X,Y,Z);
hold on
h(2) = pcolor(X,Y,Z);
hold off
set(h(2),'ZData',-10 + 0*Z)
set(h(2),'FaceColor','interp','EdgeColor','interp')
view(3)
m = 64;
cmin = min(Z(:));
cmax = max(Z(:));
C1 = min(m,round((m-1)*(Z-cmin)/(cmax-cmin))+1);
C2 = 64+C1;
set(h(1),'CData',C1);
set(h(2),'CData',C2);
caxis([min(C1(:)) max(C2(:))])
In this example, the CData properties of each object are mapped to integer values. The surface CData, C1, ranges from 1 to 64. 64 was chosen because it uses the first 64 rows of the colormap. Since the pcolor plot used the second half of the colormap, simply add 64 to C1 and the new CData matrix, C2, ranges from 65 to 128. As you can see, both C1 and C2 have the same range, 64. They are contiguous and do not overlap.
Example 2: Use a Different Colormap in Two Separate Axes
If you are using MATLAB R2014b or later release, the function "colormap" accepts the handle to axes as input and allows you to set different colormaps for each axes. For example the following code snippet will plot two subplots with different colormaps.
figure
ax1 = subplot(2,1,1);
surf(peaks)
colormap(ax1,spring)
ax2 = subplot(2,1,2);
surf(peaks)
colormap(ax2,winter)
If you are using a MATLAB R2014a and earlier, the following example with show how you can get different colormaps for two separate axes.
load clown
cmap1 = map;
cmap2 = gray(size(map,1));
cmap = [cmap1;cmap2];
colormap(cmap)
subplot(121)
image(X)
subplot(122)
X2 = X + max(X(:));
image(X2)
Note that if surface or patch plots were used instead of images, you would also have to set the CLim properties of each axis to [min(X(:)) max(X2(:))]. The following code fragment illustrates how to do this using the SET function rather than CAXIS:
ax = findobj(gcf,'Type','axes');
set(ax,'CLim', [min(X(:)) max(X2(:))])
Note that we can set the CLim property of both axes simultaneously with SET; CAXIS will only affect one axis.
If the CData is logical, it should be converted to direct indexing in order to use more than the first 2 rows of the colormap. For example, following the same process as above, but with a binary image:
load clown;
X = X>mean(X(:));
subplot(121)
h(1) = image(X);
subplot(122)
h(2) = image(X);
cmap1 = summer(2);
cmap2 = copper(2);
cmap = [cmap1;cmap2];
colormap(cmap)
h1CData = get(h(1),'CData');
h1CData = h1CData + 1;
set(h(1),'CData', h1CData );
h2CData = get(h(2),'CData');
h2CData = double(h2CData);
h2CData = h2CData + 1;
h2CData = h2CData + max(h1CData(:));
set(h(2),'CData', h2CData );
Example 3: Use Three Colormaps in a Single Axes
theta = linspace(0,2*pi,40);
rho = [5:.5:10]';
[rho,theta] = meshgrid(rho,theta);
[X,Y] = pol2cart(theta,rho);
Z = (sin(X)./X) + .05*sin(3*Y);
hm = mesh(X,Y,Z);
set(hm,'FaceColor','none','EdgeColor','k')
hold on
ax = axis;
axis(ax)
h(1) = surf(X,Y,ax(5)+0*Z,Z);
h(2) = surf(X,ax(4)+0*Y,Z);
h(3) = surf(ax(2)+0*X,Y,Z);
set(h,'FaceColor','interp','EdgeColor','interp')
cmapX = bone(32);
cmapY = cool(32);
cmapZ = jet(32);
cmap = [cmapX;cmapY;cmapZ];
colormap(cmap)
zmin = min(Z(:));
zmax = max(Z(:));
cdx = min(32,round(31*(Z-zmin)/(zmax-zmin))+1);
cdy = cdx+32;
cdz = cdy+32;
set(h(1),'CData',cdx)
set(h(3),'CData',cdy)
set(h(2),'CData',cdz)
caxis([min(cdx(:)) max(cdz(:))])
This example operates in much the same way Example 1 does. However, instead of partitioning the colormap into two pieces it partitions the colormap into three sections.
Example 4: Use Multiple Colormaps in a Single Figure
If you have the Image Processing Toolbox, you can use SUBIMAGE in conjunction with subplot to create figures with multiple images, even if the images have different colormaps. SUBIMAGE works by converting images to truecolor for display purposes, thus avoiding colormap conflicts.
More information on this can be found in the Displaying Multiple Images section of the documentation for the Image Processing Toolbox, in particular the documentation for SUBIMAGE:
https://www.mathworks.com/help/images/ref/subimage.html
Example 5: Overlay Multiple Axes with Differing Colormaps in a Single Figure
This example shows how to overlay two axes in a figure and link them. One axes contains a contourm plot of a peaks function. The other axes contains a pcolor plot of the 2nd derivative of the peaks function.
Since there is no CData property in contour plots, we can not manually assign it a portion of the colormap from the axes like Example 1 does. The contour plots automatically use the whole colormap of the axes. Instead, we can give the contour plot and pcolor plot each its own axes (with differing colormaps) and then overlay the two.
The first axes is created, set with a gray colormap, and is filled with the pcolor plot. The second axes is then created, set to be invisible with a cool colormap, and then filled with the contourm plot. Each axes also gets its own colorbar on each side of the figure with correct values. Finally, the two axes are linked so that they always mimic each others bounds. Without this, panning and zooming would only affect the last created axes which is on top of the rest.
[X,Y,Z] = peaks(30);
Zprime = del2(Z);
contourmin = min(Z(:));
contourmax = max(Z(:));
pcolormin = min(Zprime(:));
pcolormax = max(Zprime(:));
hF = figure;
hAxesP = axes;
colormap(hAxesP,gray);
pcolorPlot = pcolor(X,Y,Zprime);
set(pcolorPlot,'FaceColor','interp','EdgeColor','interp');
cbP = colorbar(hAxesP,'Location','west');
caxis(hAxesP,[pcolormin pcolormax]);
hAxesCM = axes;
axis(hAxesCM,'off')
colormap(hAxesCM,cool);
contourmPlot = contourm(X,Y,Z,20);
cbCM = colorbar(hAxesCM,'Location','east');
caxis(hAxesCM,[contourmin contourmax]);
linkaxes([hAxesP,hAxesCM]);