Matlab: same colormap for hist, plot and mesh - matlab

I have datasets for 5 different frequencies in a matrix and I want to illustrate them using plot, hist and mesh. However, each plot type is using different colormaps (see picture), so I need a legend for every plot.
Is there a way to set the same colormap for all plot types, or specify one for each of them? Another thing thats strange: I can set the colormap for hist using the figure tools for example, but not for the normal plot. For the mesh I have to use a hold on loop, so I guess setting the color here is different from defining a colormap?
Edit:
Here is a minimal example. Its still not working, see comments in the code below.
clear all;
close all;
clc;
% make up some data with the original format
freqLen = 5;
data = zeros(10, 3, 3, freqLen);
data(:, :, :, 1) = rand(10, 3, 3);
data(:, :, :, 2) = rand(10, 3, 3)+1;
data(:, :, :, 3) = rand(10, 3, 3)+2;
data(:, :, :, 4) = rand(10, 3, 3)+3;
data(:, :, :, 5) = rand(10, 3, 3)+4;
% reshape data so we get a vector for each frequency
dataF = reshape(data, [10*3*3, freqLen]);
% prepare colors for plot, try to get 5 colors over the range of colormap
% but I get wrong colors using both methods below!
%cols = colormap(jet);
%cols = cols(1:round(length(cols)/length(freqGHz)):end, :);
cols = jet(freqLen);
% plot samples in 3D
figure('Position', [0 0 1000 1000]);
subplot(211);
hold on;
for iF = 1:freqLen
dataThisF = dataF(:, iF);
data3D = reshape(dataThisF, [10*3, 3]);
mesh(data3D);
% try to give each "holded" mesh a different color. Not working!
% after the loop, all meshes have the last color
set(get(gca, 'child'), 'FaceColor', 'w', 'EdgeColor', cols(iF, :));
end
view(60, 20);
% plot samples
subplot(223);
hold on;
for iF = 1:freqLen
% the loop is not avoidable
% because matlab maps the colors wrong when plotting as a matrix
% at least its not using the colormap colors
plot(dataF(:, iF), 'Color', cols(iF, :));
end
% plot histogram
subplot(224);
% actually the only one which is working as intended, horray!
hist(dataF, 50);
How can I give a holded mesh a single color, different from the others? How can I map the correct jet colormap when plotting a matrix using simple line plot, or at least get 5 colors from the jet colormap (jet(5) give 5 different colors, but not from start to end)?

What you are talking about is mainly the ColorOrder property (and not the colormap of the figure).
The link for the colororder given just above will explain you how to force Matlab to use a given set of colors for all the plots. It works perfectly fine for plot. You wouldn't need a loop, just define the DefaultColororder property of the figure before the plots then plot all your series in one single call, Matlab will assign the color of each plot according to the order you defined earlier.
For mesh and hist it is not that simple unfortunately, so you will have to run a loop to specify the color or each graphic object. To modify a graphic object property (like the color) after it has been created, you have to use the set method, or even the direct dot notation if you're using a Matlab version >= 2014b. For both methods you needs to have the handle of the graphic object, so usually the easiest when you know you'll need that is to retrieve the graphic object handle at the time of creation*.
*instead of dirty hack like get(gca, 'child'). This is quite prone to errors and as a matter of fact was wrong in your case. Your code wouldn't color properly because you were not getting the right graphic handle this way.
The code below plots all your graphs, retrieve the handle of each graphic object, then assign the colors in the final loop.
%// Get a few colors
cols = jet(freqLen);
% plot samples in 3D
figure('Position', [0 0 1000 1000]);
set( gcf , 'DefaultAxesColorOrder',cols) %// set the line color order for this figure
subplot(2,1,1,'NextPlot','add'); %// 'NextPlot','add' == "hold on" ;
for iF = 1:freqLen
dataThisF = dataF(:, iF);
data3D = reshape(dataThisF, [10*3, 3]);
h.mesh(iF) = mesh(data3D) ; %// plot MESH and retrieve handles
%// You can set the color here direct, or in the last final "coloring" loop
%// set( h.mesh(iF) , 'FaceColor', 'w', 'EdgeColor', cols(iF, :));
end
view(60, 20);
%// plot samples
subplot(223);
h.plots = plot(dataF); %// plot LINES and retrieve handles
%// plot histogram
subplot(224);
[counts,centers] = hist(dataF, 50 ) ; %// get the counts values for each series
h.hist = bar(centers,counts) ; %// plot HISTOGRAM and retrieve handles
%// now color every series with the same color
for iF = 1:freqLen
thisColor = cols(iF, :) ;
set( h.mesh(iF) , 'EdgeColor' , thisColor , 'FaceColor', 'w' );
set( h.hist(iF) , 'EdgeColor' , thisColor , 'FaceColor' , thisColor )
%// this is actually redundant, the colors of the plots were already right from the
%// beginning thanks to the "DefaultColorOrder" property we specified earlier
set( h.plots(iF) , 'Color' , thisColor )
end
Will land you the following figure:

UPDATE: The original question asked
Is there a way to set the same colormap for all plot types, or specify one for each of them?
this answer, answers that question with colormap taken to mean colormap in MATLAB literally.
You can set the colormap for a figure using colormap. You could use one of the many built in colormaps or specify your own.
An example using mesh and the builtin hsv colormap could be
figure;
mesh(data);
colormap(hsv);
This would apply a colormap based on
to your figure. You can also create your own colormap like
map = [1, 0, 0,
1, 1, 1,
0, 1, 0,
0, 0, 0];
colormap(map);
which would create a colormap with the colours Red, White, Blue and Black.
The MATLAB documentation contains extensive information on the use of colormap.

Related

Plot rows of a 2d matrix in matlab

I have a 2d matrix A (100 x 100) where each row contains a signal to be plot.
I want to plot all of the signals in the same figure with different color for each row. How can I do this easily?
If you actually look at the documentation for plot you'll see that if you pass it a matrix, it will plot each column as a separate plot object on the same axes. As such you can simply pass the transpose of your data to plot.
% Example data
A = magic(10);
% Create a plot for each row
hplot = plot(A.');
This will plot each signal using the next plot color.
If you want to ensure that you have all different colors, you can use a colormap (such as parula) to explicitly set a different color per plot.
set(hplot, {'Color'}, num2cell(parula(size(A, 1)), 2))
Update
If you want to label your plots you could simply use legend to do this.
displaynames = arrayfun(#(x)sprintf('Plot %d', x), 1:size(A, 1), 'uni', 0);
set(hplot, {'DisplayName'}, displaynames.');
legend(hplot)
Or if you have too many plots to reasonably fit within a legend you can create an interactive plot that highlights a given plot when you mouseover it. Here is an example of such a thing.
htitle = title('');
set(gcf, 'WindowButtonMotionFcn', #(s,e)motionCallback(hittest(s)))
motionCallback(hplot(1));
function motionCallback(plt)
% Don't do anything if not a line object
[tf, ind] = ismember(plt, hplot);
if ~tf; return; end
set(hplot, 'linewidth', 1)
set(plt, 'LineWidth', 3)
set(htitle, 'String', sprintf('SelectedPlot: %d', ind))
drawnow
end
And the result

Use multiple colorbars in one figure [duplicate]

I am fairly new to Matlab and have a few questions.
I got two surfaces and a plane in the same figure.
I want to use different colormap and colorbar for b and another colormap and colorbar for c. s is fixed color so it's not a problem.
Let me try to explain what I am trying to achieve:
cmap1=colormap(topobathy) -->cmap1 is 64x3 double as expected
cmap2=colormap(redwhitegreen)
create cdata1 using cmap1 (this is the first part I cannot figure out, how to scale z data using cmap1, by default CData contains the z values)
b=surf(x,y,z,cdata1)
colorbar for b using z values
c=pcolor(x,y,(z-z0)) - I want to use cmap2 for this one.
colorbar for c using (z-z0) values
Here is what I have so far and the problems I encounter
b=surf(x,y,z);
colormap(topobathy);
cbar1=colorbar;
set(get(cbar1,'ylabel'),'String', 'Elevation (m)', 'Rotation', 90)
hold on;
s=surf(x,y,z1,'FaceColor',[0.278 0.788 0.788])
hold on;
change=z-z0;
c=pcolor(x,y,change)
set(c,'ZData',100 + 0*change); %plotting it above the other surfaces
colormap(redwhitegreen)`
at this point colormap is set to redwhitegreen for b, colorbar of b
I can't get the second colorbar with its own clim etc.
I used the freezeColors and cbfreeze explained in this link:
http://blogs.mathworks.com/pick/2009/07/24/using-multiple-colormaps-in-a-single-figure/
but one thing works while messing another thing (probably all my fault). I want to learn how to have complete control over my objects without using external m files anyway.
Any help is appreciated.
The basic idea is that you concatenate the colormaps, and then shift/scale the color data (CData) of the different plot handles to line up with the desired portions of the colormap. So, without knowing what your custom functions or specific data are, you could do something like colormap(topobathy(64); redwhitegreen(64)) and then scale the CData of b into the range [1,64] and the CData of c into the range [65,128].
There is an excellent guide on the MathWorks website that explains all this (even uses surf() and pcolor() like your example):
http://www.mathworks.com/support/tech-notes/1200/1215.html#Example_1
For the colorbar, you can just fake out the ticks and labels in a similar manner. Here is rough shot at making a color bar for the above example:
h = colorbar;
ticks = [1 16:16:64 64:16:128];
ticks(5:6) = [62 66];
set(h, 'YTick', ticks);
labels = num2str(repmat(linspace(min(Z(:)), max(Z(:)), 5), 1, 2)', 2);
set(h, 'YTickLabel', labels)
I had the same problem as you, and the best (and only) solution I found was the next:
Concatenate both colormaps I wanted:
cmap1 = jet(64); cmap2 = copper(64); color_map = [cmap1 ; cmap2];
So, the first colormap (cmap1) will be used for Axes1, and the second colormap (cmap2) for Axes2. I guess that Axes1 and Axes2 are in the same figure.
Normalize data, giving a scale from 0 to 1 for data of Axes1, and from 1 to 2 for data of Axes2. So, Axes1 in [0, 1] and Axes2 in [1 2].
data1 = data1 - lower_limit1;
data1 = double(data1./(upper_limit1 - lower_limit1));
For data set of Axes 2:
data2 = data2 - lower_limit;
data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
When representing them:
Axes1:
pcolor(handle_axes1, x_axis, y_axis, data1); shading(handle_axes1,'FLAT');
caxis(handle_axes1, [0 2]);
% Colorbar
h_colorbar = colorbar('peer', handle_axes1);
set(h_colorbar, 'YLim', [0 1]);
labels = num2str(linspace(lower_limit1, upper_limit1, 6)', 2);
set(h_colorbar, 'YTick', linspace(0, 1, 6));
set(h_colorbar, 'YTickLabel', labels);
Axes2:
pcolor(handle_axes2, x_axis, y_axis, data2); shading(handle_axes2,'FLAT');
caxis(handle_axes2, [0 2]);
% Colorbar
h_colorbar2 = colorbar('peer', handle_axes2);
set(h_colorbar2, 'YLim', [1 2]);
labels = num2str(linspace(lower_limit2, upper_limit2, 6)', 2);
set(h_colorbar2, 'YTick', linspace(1, 2, 6));
set(h_colorbar2, 'YTickLabel', labels);
Use pcolor or surf, depending on your needs.
Hope it helps!
Matlab has provided code for a function newclim which solves this problem cleanly by concatenating the colormaps into one colormap. I could only find this documentation on the 2012b Help, but not online.
Note that the axes used to update the CLim as the last step could be axes to surf plots, which is how I applied this code.
Calculating Color Limits
The key to this example is calculating values for CLim that cause each surface to use the section of the colormap containing the appropriate colors.
To calculate the new values for CLim, you need to know
The total length of the colormap (CmLength)
The beginning colormap slot to use for each axes (BeginSlot)
The ending colormap slot to use for each axes (EndSlot)
The minimum and maximum CData values of the graphic objects contained
in the axes. That is, the values of the axes CLim property determined
by MATLAB when CLimMode is auto (CDmin and CDmax).
First, define subplot regions and plot the surfaces.
im1 = load('cape.mat');
im2 = load('flujet.mat');
ax1 = subplot(1,2,1);
imagesc(im1.X)
axis(ax1,'image')
ax2 = subplot(1,2,2);
imagesc(im2.X)
axis(ax2,'image')
Concatenate two colormaps and install the new colormap.
colormap([im1.map;im2.map])
Obtain the data you need to calculate new values for CLim.
CmLength = length(colormap); % Colormap length
BeginSlot1 = 1; % Beginning slot
EndSlot1 = length(im1.map); % Ending slot
BeginSlot2 = EndSlot1 + 1;
EndSlot2 = CmLength;
CLim1 = get(ax1,'CLim'); % CLim values for each axis
CLim2 = get(ax2,'CLim');
Defining a Function to Calculate CLim Values
Computing new values for CLim involves determining the portion of the colormap you want each axes to use relative to the total colormap size and scaling its Clim range accordingly. You can define a MATLAB function to do this.
function CLim = newclim(BeginSlot,EndSlot,CDmin,CDmax,CmLength)
% Convert slot number and range
% to percent of colormap
PBeginSlot = (BeginSlot - 1) / (CmLength - 1);
PEndSlot = (EndSlot - 1) / (CmLength - 1);
PCmRange = PEndSlot - PBeginSlot;
% Determine range and min and max
% of new CLim values
DataRange = CDmax - CDmin;
ClimRange = DataRange / PCmRange;
NewCmin = CDmin - (PBeginSlot * ClimRange);
NewCmax = CDmax + (1 - PEndSlot) * ClimRange;
CLim = [NewCmin,NewCmax];
end
The input arguments are identified in the bulleted list above. The function first computes the percentage of the total colormap you want to use for a particular axes (PCmRange) and then computes the CLim range required to use that portion of the colormap given the CData range in the axes. Finally, it determines the minimum and maximum values required for the calculated CLim range and returns these values. These values are the color limits for the given axes.
Using the Function
Use the newclim function to set the CLim values of each axes. The statement
set(ax1,'CLim',newclim(BeginSlot1,EndSlot1,CLim1(1),...
CLim1(2),CmLength))
sets the CLim values for the first axes so the surface uses color slots 65 to 120. The lit surface uses the lower 64 slots. You need to reset its CLim values as well.
set(ax2,'CLim',newclim(BeginSlot2,EndSlot2,CLim2(1),...
CLim2(2),CmLength))
How the Function Works
MATLAB enables you to specify any values for the axes CLim property, even if these values do not correspond to the CData of the graphics objects displayed in the axes. The minimum CLim value is always mapped to the first color in the colormap and the maximum CLim value is always mapped to the last color in the colormap, whether or not there are really any CData values corresponding to these colors. Therefore, if you specify values for CLim that extend beyond the object's actual CData minimum or maximum, MATLAB colors the object with only a subset of the colormap.
The newclim function computes values for CLim that map the graphics object's actual CData values to the beginning and ending colormap slots that you specify. It does this by defining a "virtual" graphics object having the computed CLim values.

How to set colorbar labels

I have some points in a 'jet' colormap. The points have a coefficient that can go from 0 to 1, but usually they dont cover all the range, e.g 0.75-0.9.
When I plot those points I colour them so 0.75 is the lesser colour in the colormap and 0.9 is the maximum color in the colormap, so all the colormap is shown. What I want to do is show that in the colorbar also. When I plot the colorbar the labels on it go to 64, but I want them from 0.75 to 0.9. How can I do that?
EDIT
I don't think the code itself helps a lot but here it goes, just in case. In the colors variable I convert the ZNCC to the range of the colormap.
EDIT2
I found the reason why caxis is not working for me. Here is the code:
%this is why it doesnt work
im=imread('someimageyouwanttotest_inRGB.png')
imshow(im)
points=[1, 2;1 , 2 ;0.3,0.7]
ZNCC=points(3,:)
cmap=colormap('jet');
colors=cmap(round( ((1-min(ZNCC))+ZNCC-1).*(size(cmap,1)-1)/max((1-min(ZNCC))+ZNCC-1))+1,: );
hold on
for i=1:length(ZNCC)
plot(points(1,i),points(2,i),'.','Color',colors(i,:));
end
colorbar()
hold off
I think that is your code displays all your colours correctly then rather just set up the colour bar first on no image:
points=[1, 2;1 , 2 ;0.3,0.7]
ZNCC=points(3,:)
cmap=colormap('jet');
caxis([min(ZNCC) max(ZNCC)]);
colorbar();
hold on
%this is why it doesnt work
im=imread('someimageyouwanttotest_inRGB.png')
imshow(im)
colors=cmap(round( ((1-min(ZNCC))+ZNCC-1).*(size(cmap,1)-1)/max((1-min(ZNCC))+ZNCC-1))+1,: );
for i=1:length(ZNCC)
plot(points(1,i),points(2,i),'.','Color',colors(i,:));
end
hold off
I can't test it as I don't have imshow :/
If caxis is not working for you, you could store the return from colorbar - it is a handle to the colorbar object. Then you can set its properties, like 'YTick' and 'YLim'. The full list of properties you can set is the same as the Axes Properties (because the colorbar is just an axes object, after all).
Here is an example:
% Generate some random data
z = rand(10);
[x, y] = meshgrid(1:size(z, 1));
% Plot colour map
pcolor(x, y, z);
shading interp; % Comment out to disable colour interpolation
colormap jet;
% Setup colorbar
c = colorbar();
set(c, 'YTick', [0.75 0.875 1]); % In this example, just use three ticks for illustation
ylim(c, [0.75 1]);
It is only necessary to do this once, after you've finished plotting.
Edit: If you need the limits and ticks automatically from the data, then you can do something like
% Find the limits
lims = [min(z(:)) max(z(:))];
% Function for rounding to specified decimal places
dprnd = #(x, dps)round(x*(10.^dps))./(10.^dps);
% Generate ticks
nTicks = 5;
nDps = 2;
ticks = dprnd(linspace(lims(1), lims(2), nTicks), nDps);
set(c, 'YTick', ticks);

Matlab: How to assign different colormaps/colorbars to different surfaces in the same Figure

I am fairly new to Matlab and have a few questions.
I got two surfaces and a plane in the same figure.
I want to use different colormap and colorbar for b and another colormap and colorbar for c. s is fixed color so it's not a problem.
Let me try to explain what I am trying to achieve:
cmap1=colormap(topobathy) -->cmap1 is 64x3 double as expected
cmap2=colormap(redwhitegreen)
create cdata1 using cmap1 (this is the first part I cannot figure out, how to scale z data using cmap1, by default CData contains the z values)
b=surf(x,y,z,cdata1)
colorbar for b using z values
c=pcolor(x,y,(z-z0)) - I want to use cmap2 for this one.
colorbar for c using (z-z0) values
Here is what I have so far and the problems I encounter
b=surf(x,y,z);
colormap(topobathy);
cbar1=colorbar;
set(get(cbar1,'ylabel'),'String', 'Elevation (m)', 'Rotation', 90)
hold on;
s=surf(x,y,z1,'FaceColor',[0.278 0.788 0.788])
hold on;
change=z-z0;
c=pcolor(x,y,change)
set(c,'ZData',100 + 0*change); %plotting it above the other surfaces
colormap(redwhitegreen)`
at this point colormap is set to redwhitegreen for b, colorbar of b
I can't get the second colorbar with its own clim etc.
I used the freezeColors and cbfreeze explained in this link:
http://blogs.mathworks.com/pick/2009/07/24/using-multiple-colormaps-in-a-single-figure/
but one thing works while messing another thing (probably all my fault). I want to learn how to have complete control over my objects without using external m files anyway.
Any help is appreciated.
The basic idea is that you concatenate the colormaps, and then shift/scale the color data (CData) of the different plot handles to line up with the desired portions of the colormap. So, without knowing what your custom functions or specific data are, you could do something like colormap(topobathy(64); redwhitegreen(64)) and then scale the CData of b into the range [1,64] and the CData of c into the range [65,128].
There is an excellent guide on the MathWorks website that explains all this (even uses surf() and pcolor() like your example):
http://www.mathworks.com/support/tech-notes/1200/1215.html#Example_1
For the colorbar, you can just fake out the ticks and labels in a similar manner. Here is rough shot at making a color bar for the above example:
h = colorbar;
ticks = [1 16:16:64 64:16:128];
ticks(5:6) = [62 66];
set(h, 'YTick', ticks);
labels = num2str(repmat(linspace(min(Z(:)), max(Z(:)), 5), 1, 2)', 2);
set(h, 'YTickLabel', labels)
I had the same problem as you, and the best (and only) solution I found was the next:
Concatenate both colormaps I wanted:
cmap1 = jet(64); cmap2 = copper(64); color_map = [cmap1 ; cmap2];
So, the first colormap (cmap1) will be used for Axes1, and the second colormap (cmap2) for Axes2. I guess that Axes1 and Axes2 are in the same figure.
Normalize data, giving a scale from 0 to 1 for data of Axes1, and from 1 to 2 for data of Axes2. So, Axes1 in [0, 1] and Axes2 in [1 2].
data1 = data1 - lower_limit1;
data1 = double(data1./(upper_limit1 - lower_limit1));
For data set of Axes 2:
data2 = data2 - lower_limit;
data2 = double(data2./(upper_limit2 - lower_limit2)) + 1;
When representing them:
Axes1:
pcolor(handle_axes1, x_axis, y_axis, data1); shading(handle_axes1,'FLAT');
caxis(handle_axes1, [0 2]);
% Colorbar
h_colorbar = colorbar('peer', handle_axes1);
set(h_colorbar, 'YLim', [0 1]);
labels = num2str(linspace(lower_limit1, upper_limit1, 6)', 2);
set(h_colorbar, 'YTick', linspace(0, 1, 6));
set(h_colorbar, 'YTickLabel', labels);
Axes2:
pcolor(handle_axes2, x_axis, y_axis, data2); shading(handle_axes2,'FLAT');
caxis(handle_axes2, [0 2]);
% Colorbar
h_colorbar2 = colorbar('peer', handle_axes2);
set(h_colorbar2, 'YLim', [1 2]);
labels = num2str(linspace(lower_limit2, upper_limit2, 6)', 2);
set(h_colorbar2, 'YTick', linspace(1, 2, 6));
set(h_colorbar2, 'YTickLabel', labels);
Use pcolor or surf, depending on your needs.
Hope it helps!
Matlab has provided code for a function newclim which solves this problem cleanly by concatenating the colormaps into one colormap. I could only find this documentation on the 2012b Help, but not online.
Note that the axes used to update the CLim as the last step could be axes to surf plots, which is how I applied this code.
Calculating Color Limits
The key to this example is calculating values for CLim that cause each surface to use the section of the colormap containing the appropriate colors.
To calculate the new values for CLim, you need to know
The total length of the colormap (CmLength)
The beginning colormap slot to use for each axes (BeginSlot)
The ending colormap slot to use for each axes (EndSlot)
The minimum and maximum CData values of the graphic objects contained
in the axes. That is, the values of the axes CLim property determined
by MATLAB when CLimMode is auto (CDmin and CDmax).
First, define subplot regions and plot the surfaces.
im1 = load('cape.mat');
im2 = load('flujet.mat');
ax1 = subplot(1,2,1);
imagesc(im1.X)
axis(ax1,'image')
ax2 = subplot(1,2,2);
imagesc(im2.X)
axis(ax2,'image')
Concatenate two colormaps and install the new colormap.
colormap([im1.map;im2.map])
Obtain the data you need to calculate new values for CLim.
CmLength = length(colormap); % Colormap length
BeginSlot1 = 1; % Beginning slot
EndSlot1 = length(im1.map); % Ending slot
BeginSlot2 = EndSlot1 + 1;
EndSlot2 = CmLength;
CLim1 = get(ax1,'CLim'); % CLim values for each axis
CLim2 = get(ax2,'CLim');
Defining a Function to Calculate CLim Values
Computing new values for CLim involves determining the portion of the colormap you want each axes to use relative to the total colormap size and scaling its Clim range accordingly. You can define a MATLAB function to do this.
function CLim = newclim(BeginSlot,EndSlot,CDmin,CDmax,CmLength)
% Convert slot number and range
% to percent of colormap
PBeginSlot = (BeginSlot - 1) / (CmLength - 1);
PEndSlot = (EndSlot - 1) / (CmLength - 1);
PCmRange = PEndSlot - PBeginSlot;
% Determine range and min and max
% of new CLim values
DataRange = CDmax - CDmin;
ClimRange = DataRange / PCmRange;
NewCmin = CDmin - (PBeginSlot * ClimRange);
NewCmax = CDmax + (1 - PEndSlot) * ClimRange;
CLim = [NewCmin,NewCmax];
end
The input arguments are identified in the bulleted list above. The function first computes the percentage of the total colormap you want to use for a particular axes (PCmRange) and then computes the CLim range required to use that portion of the colormap given the CData range in the axes. Finally, it determines the minimum and maximum values required for the calculated CLim range and returns these values. These values are the color limits for the given axes.
Using the Function
Use the newclim function to set the CLim values of each axes. The statement
set(ax1,'CLim',newclim(BeginSlot1,EndSlot1,CLim1(1),...
CLim1(2),CmLength))
sets the CLim values for the first axes so the surface uses color slots 65 to 120. The lit surface uses the lower 64 slots. You need to reset its CLim values as well.
set(ax2,'CLim',newclim(BeginSlot2,EndSlot2,CLim2(1),...
CLim2(2),CmLength))
How the Function Works
MATLAB enables you to specify any values for the axes CLim property, even if these values do not correspond to the CData of the graphics objects displayed in the axes. The minimum CLim value is always mapped to the first color in the colormap and the maximum CLim value is always mapped to the last color in the colormap, whether or not there are really any CData values corresponding to these colors. Therefore, if you specify values for CLim that extend beyond the object's actual CData minimum or maximum, MATLAB colors the object with only a subset of the colormap.
The newclim function computes values for CLim that map the graphics object's actual CData values to the beginning and ending colormap slots that you specify. It does this by defining a "virtual" graphics object having the computed CLim values.

Matlab Ploting with different color for iso-surface

I was trying use the code shown below to plot in such a way that each iso-surface will be different in color and there will be a color bar at the right. I made a ss(k) color matrix for different colors. Number of iso-surfaces is 10 but I have only 8 colors. That's why I wrote ss(9)='r' and ss(10)='r'.
I need a solution to plot the iso-surface with different color and bar at the right side.
ss=['y','m','c','r','g','b','w','k','r','r']
k=1;
for i=.1:.1:1
p=patch(isosurface(x,y,z,v,i));
isonormals(x,y,z,v,p)
hold on;
set(p,'FaceColor',ss(k),'EdgeColor','none');
daspect([1,1,1])
view(3); axis tight
camlight
lighting gouraud
k=k+1;
end
Another possibility is to draw the patches with direct color-mapping (by setting the property 'CDataMapping'='direct'), while assigning the 'CData' of each patch to an index in the colormap of your choice. This is in fact recommended for maximum graphics performance.
Consider the following example:
%# volumetric data, and iso-levels we want to visualize
[x,y,z,v] = flow(25);
isovalues = linspace(-2.5,1.5,6);
num = numel(isovalues);
%# plot isosurfaces at each level, using direct color mapping
figure('Renderer','opengl')
p = zeros(num,1);
for i=1:num
p(i) = patch( isosurface(x,y,z,v,isovalues(i)) );
isonormals(x,y,z,v,p(i))
set(p(i), 'CData',i);
end
set(p, 'CDataMapping','direct', 'FaceColor','flat', 'EdgeColor','none')
%# define the colormap
clr = hsv(num);
colormap(clr)
%# legend of the isolevels
%#legend(p, num2str(isovalues(:)), ...
%# 'Location','North', 'Orientation','horizontal')
%# fix the colorbar to show iso-levels and their corresponding color
caxis([0 num])
colorbar('YTick',(1:num)-0.5, 'YTickLabel',num2str(isovalues(:)))
%# tweak the plot and view
box on; grid on; axis tight; daspect([1 1 1])
view(3); camproj perspective
camlight; lighting gouraud; alpha(0.75);
rotate3d on
I also included (commented) code to display the legend, but I found it to be redundant, and a colorbar looks nicer.
Matlab usually plots different iso-surfaces in different colors automatically, so you don't need to care about that. What kind of bar do you need? A colorbar or a legend? Either way, it is just to use the colorbar or legend function..
%Create some nice data
[x y z] = meshgrid(1:5,1:5,1:5);
v = ones(5,5,5);
for i=1:5
v(:,:,i)=i;
end
v(1:5,3:5,2)=1
v(1:5,4:5,3)=2
%Plot data
for i=1:5
isosurface(x,y,z,v,i)
end
%Add legend and/or colorbar
legend('one','Two','Three','Four')
colorbar
Since the color bar encodes value->color, it is impossible to do what you ask for, unless there is no intersection in z-values between all pairs of surfaces. So the solution below assumes this is the case. If this is not the case, you can still achieve it by adding a constant value to each surface, so to separate the surfaces along the z axis, and eliminate any intersection.
The solution is based on constructing a colormap matrix of piecewise constant values, distributed similarly to the z values of your surfaces. So for example, if you have 3 surfaces, the first has z values between 1 and 10, the 2nd between 11 and 30, and the 3rd between 31 and 60, you should do something like this (I plot in 2D for simplicity)
r = [1 0 0];
g = [0 1 0];
b = [0 0 1];
cmap = [r(ones(10,1),:); g(ones(20,1),:); b(ones(30,1),:)];
z1 = 1:10;
z2 = 11:30;
z3 = 31:60;
figure; hold on
plot(z1,'color',r)
plot(z2,'color',g)
plot(z3,'color',b)
colorbar
colormap(cmap)
More complex colormaps (i.e, more colors) can be constructed with different mixtures of red, green, and blue (http://www.mathworks.com/help/techdoc/ref/colorspec.html)