5
votes

I have a terrain map which i would like to represent some data in. See the below picture:

enter image description here

The area on the right circled by white is a separate surf function to the remainder of the plot. What I would like to be able to do is change the colour scheme. The outside should be grey scale and the inside should be a single colour based on a value that I have separate to the plot. Currently I have tried the colormap(gray) function then changing but that changes the entire plot.

I am open to suggestions about differant plotting styles ie. plot3 instead of surf. So the data i have to make these two surfs are two lists of x, y, z points.

If possible I would also like to display a colour bar that represents the colour of the circled area (which will be set by me based on the outside value).

Does anyone know of a good way to do this?

Thanks.

EDIT:

What i would like to do is this:

enter image description here

The Image should not have the dark blue at the top of the mound. The image will be continually update with more of the 'blue' spots, the colour should change based on an external value and ideally it will merge colours with the previous spots if they overlap.

2

2 Answers

2
votes

Have you seen this from MATLAB Tech Support?

http://www.mathworks.com/support/solutions/en/data/1-GNRWEH/index.html

You can edit the colorbar properties.

g = colorbar;
get(g)

For example,

% Define a colormap that uses the cool colormap and 
% the gray colormap and assign it as the Figure's colormap.
colormap([cool(64);gray(64)])


% Generate some surface data.
[X,Y,Z] = peaks(30);


% Produce the two surface plots.
h(1) = surf(X,Y,Z);
hold on
h(2) = pcolor(X,Y,Z);
hold off


% Move the pcolor to Z = -10.
% The 0*Z is in the statement below to insure that the size
% of the ZData does not change.
set(h(2),'ZData',-10 + 0*Z)
set(h(2),'FaceColor','interp','EdgeColor','interp')
view(3)


% Scale the CData (Color Data) of each plot so that the 
% plots have contiguous, nonoverlapping values. The range 
% of each CData should be equal. Here the CDatas are mapped 
% to integer values so that they are easier to manage; 
% however, this is not necessary.


% Initially, both CDatas are equal to Z.
m = 64; % 64-elements is each colormap


cmin = min(Z(:));
cmax = max(Z(:));
% CData for surface
C1 = min(m,round((m-1)*(Z-cmin)/(cmax-cmin))+1); 
% CData for pcolor
C2 = 64+C1;


% Update the CDatas for each object.
set(h(1),'CData',C1);
set(h(2),'CData',C2);


% Change the CLim property of axes so that it spans the 
% CDatas of both objects.
caxis([min(C1(:)) max(C2(:))])

% I added these two lines
g = colorbar
set(g,'YLim',[1 60])

The last two lines are mine. The rest is from the MATLAB Tech Support link. And it will give you a colorbar with just one colormap. If you wanted the gray half of the colormap, then you would do set(g,'YLim',[64 128]).

enter image description here

7
votes

Since you want to set the circled area to a single color only, you can set it's FaceColor property. For example:

%# make some test data
[xx,yy]=ndgrid(-5:0.1:5,-5:0.1:5);
zz = exp(-xx.^2/2+-yy.^2/2);
zz1 = zz;
zz1(zz1>0.5)=NaN;
zz2 = zz;
zz2(zz2<0.5)=NaN;

%# plot first surface, set colormap
surf(zz1)
colormap('gray')

%# stretch colormap to [0 0.5]
caxis([0 0.5])

%# plot the second surface in red
hold on
surf(zz2,'faceColor','r')

enter image description here

EDIT

If you want to have different colormaps for parts of your surfaces, you need to set the 'CData' property of the surfaces to indices into the colormap. To only show a single colormap in the colorbar, you can make use of the fact that the colorbar is simply another plot, which means that you can show only part of it, and change the labels.

%# make some more test data
[xx,yy]=ndgrid(-5:0.1:5,-5:0.1:5);
zz = exp(-xx.^2/2+-yy.^2/2);
zz1 = zz(1:50,:);
zz2 = zz(52:end,:);
xx1 = xx(1:50,:);xx2=xx(52:end,:);
yy1 = yy(1:50,:);yy2=yy(52:end,:);

%# create multi-colormap, set it to figure
figure
cmap = [gray(128);copper(128)];
colormap(cmap)

%# plot surfaces, setting the cdata property to indices 1-128 and 129-256, 
%# respectively, in order to access the different halves of the colormap
surf(xx1,yy1,zz1,'cdata',round(127*(zz1-min(zz1(:))/(max(zz1(:))-min(zz1(:)))))+1,'cdatamapping','direct')
hold on
surf(xx2,yy2,zz2,'cdata',round(127*(zz2-min(zz2(:))/(max(zz2(:))-min(zz2(:)))))+129,'cdatamapping','direct')

%# find the handle to the colorbar
%# alteratively: cbarH = findall(gcf,'tag','Colorbar')
cbarH = colorbar;

%# set limits and ticks/labels
ylim(cbarH,[129 255])
set(cbarH,'ytick',[129 192 255],'yticklabel',[0 0.5 1])

enter image description here