1
votes

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

enter image description here

3
No answer yet................strange - gman
it is not really clear what your problem is... your code can't be run like this because you don't define x, ... not very motivating to answer :-( - Jonas Heidelberg

3 Answers

3
votes

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

screenshot

I also included (commented) code to display the legend, but I found it to be redundant, and a colorbar looks nicer.

1
votes

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

Image

0
votes

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)

custom colorbar

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)