Plotting a rectangle with colour representing a value in Matlab - matlab

I would like to plot a number of rectangles, all of which have an associated value. I can plot points with values using scatter(x,y,[],value); but the rectangle function does not seem to have such functionality.
Thank you

You can set the rectangle color, although not quite as a direct analog to how you do with scatter. When using rectangle, you have two color options; the edge color and the face color. To set the edge color, use a 3-element vector representing the RGB values, such that each element is within the range [0, 1].
e.g.
%make some arbitrary rectangle (in this case, located at (0,0) with [width, height] of [10, 20])
rect_H = rectangle('Position', [0, 0, 10, 20]);
%sets the edge to be green
set(rect_H, 'EdgeColor', [0, 1, 0])
The face color of the rectangle is its fill-color -- you can set that by using a color string (e.g. 'g' is green, 'r' is red, etc) or by using a 3-element vector in the same manner as the edge color property.
e.g. these 2 commands will have the same effect:
set(rect_H, 'FaceColor', 'r');
set(rect_H, 'FaceColor', [1, 0, 0]);
In your case, you would just need some mapping for your value (whatever form it may be in) to a 3-element RGB color vector. I'm not sure what your goal is for the coloring, but if all you're looking for it to have all the rectangle colors be different, you could use some mapping function along the lines of:
color_map = #(value) ([mod((rand*value), 1), mod((rand*value), 1), mod((rand*value), 1)])
then have
set(rect_H, 'FaceColor', color_map(value));
where value is assumed to be a scalar. Also, if you're looking to do everything on one line akin to scatter you can do that too:
rectangle('Position', [x, y, w, h], 'FaceColor', color_map(value));
UPDATE:
To have this work nicely with colorbar, you'd have to save each of your 3-element color vectors, and pass it to the matlab built-in function colormap. Then call colorbar. I have no idea what kind of color mapping you're using, so just for the sake of illustration:
figure;
hold on;
%have 20 rectangles
num_rects = 20;
%place your rectangles in random locations, within a [10 x 10] area, with
%each rectange being of size [1 x 1]
random_rectangles = [rand(num_rects, 2)*10, ones(num_rects,2)];
%assign a random color mapping to each of the 20 rectangles
rect_colors = rand(num_rects,3);
%plot each rectangle
for i=1:num_rects
rectangle('Position', random_rectangles(i,:), 'FaceColor', rect_colors(i,:));
end
%set the colormap for your rectangle colors
colormap(rect_colors);
%adds the colorbar to your plot
colorbar
Hopefully that's what you were asking about...

Related

Changing the transparency of patches based on their value

I have a matrix containing integers ranging from 0 to 20. The regions with the same integer are formed in a quite random fashion. I want to color code each integer with a different degree of grayscale. So for example, for regions with 0, I want them to be white, then for regions with 1, 5% transparency of black, for regions with 2, 10% transparency of black,..., for regions with 20, totally black.
I've tried to get the coordinates of each region, but that does not seem to be efficient for my matrix.
How can I change the transparency of my regions based on their value?
You can use surface() with its FaceAlpha name-value pair. It only accepts scalars though, so you'll have to plot each of your patches separately, something along the lines of:
% Create a random matrix with values 1 - 20 for plotting
my_matrix = ceil(20* rand(30));
% Build its x and y grids
[x, y] = meshgrid(1:30, 1:30);
% Open and hold the figure
figure;
hold on
for ii = unique(my_matrix)
% Create a mask for the current value
temp_colour = nan(size(my_matrix));
temp_colour(my_matrix == ii) = 1;
surface(x, y, ones(size(my_matrix)), ...
temp_colour, ...
'EdgeColor', 'none', ...
'FaceAlpha', 1 - ii/max(my_matrix, 'all'))
colormap(gray)
end
Results in, on my R2007b,
If you're good with just a gray-scale image, rather than true transparency, you can simply use imagesc(my_matrix); colormap(gray).

Refine colormap for a surface plot in matlab

colorbar;
colormap hot;
x = colorbar;
caxis([-450,-100]);
x = set(x,'YTick',-450:25:-100);
ax = gca;
ax.XAxis.Label.String='x';
ax.YAxis.Label.String='y';
set(gca,'YTick',[0 5 10 15 20 25 30 35 40 45 50 55 60]);
set(gca,'XTick',[0 5 10 15 20])
set(gcf,'Color','cyan');
I'm trying to refine the color on the surface shown below. How can I adjust the steps? Using caxis([-450,-100]) makes the step linearly equal to 100. How can I get a smooth color on the surface plot? I've been reading about it on the internet, but I couldn't do it, so I ask. Thank you.
These are some parameters that can help you to get a smoother plot:
Number of colors in the colormap
Number of surfaces
How the surfaces are colored
This is a simple demonstration that shows how each parameter affect the generated plot:
f = #(mnp, n, facecolor){ subplot(mnp); ...
surf(peaks(n), 'edgecolor', 'none', ...
'facecolor', facecolor); view(2); ...
title(sprintf('Grid: %d x %d, FaceColor: %s', n, n, facecolor)); ...
colorbar};
f(221, 15, 'flat');
f(222, 15, 'interp');
f(223, 40, 'flat');
f(224, 40, 'interp');
colormap(jet(10))
figure
f(221, 15, 'flat');
f(222, 15, 'interp');
f(223, 40, 'flat');
f(224, 40, 'interp');
colormap(jet(100))
and this is the output:
Number of Colors in the Colormap
You already know that:
The size of the colormap determines how smooth the transition is between colors. A colormap with a small number of colors has sharp transitions between colors. A larger colormap provides much smoother transitions between colors.
But it probably doesn't make any changes in your case, so continue reading.
Number of surfaces
As you can see in the sample code above, plots are drawn for two different numbers of surfaces. In first and third rows a grid of 15 by 15 surfaces are plotted, while in second and forth rows there are 40 by 40 surfaces (more information about peaks(n)). Seems like your data is a 5 by 13 matrix of values. Try to plot more surfaces, if you have a function that gives the value of z on each (x, y).
How the surfaces are colored
You can see the difference between first and second columns. This is how the FaceColor property of a surface object changes how it looks.
'flat' — Use uniform face colors. Use the CData values. The color data at the first vertex determines the color for the entire face.
'interp' — Interpolate the face colors. Bilinear interpolation of the CData values at each vertex determines the colors.
What if there was no function to generate more surfaces and linear interpolation of colors was not enough?
You can use interp2 function to generate more points. This is a sample:
% original data (7 by 7)
[X,Y] = meshgrid(-3:3);
Z = peaks(X,Y);
% cubic interpolation of original data(61 by 61)
[XI,YI] = meshgrid(-3:.1:3);
ZI = interp2(X,Y,Z,XI,YI,'cubic');
% plot data (both original and interpolated)
subplot(121);
surf(X, Y, Z, 'edgecolor', 'none');
view(2);axis square
subplot(122);
surf(XI, YI, ZI, 'edgecolor', 'none', 'facecolor', 'interp');
view(2);axis square
colormap(hot(300))
And the result:

Vary color across plot points

The following code plots 3 points, all in red:
a = reshape([92.571251 94.869889 97.283709 ],[3 1]);
b = reshape([271.000000 296.000000 330.000000 ],[3 1]);
c = reshape([0.916000 0.766000 0.562000 ],[3 1]);
figure(100);
line(b,a,...
'MarkerFaceColor',[1 0 0],...
'Marker','o',...
'LineStyle','none',...
'Color',[1 0 0]);
Is there a way for me to vectorize the red portion of the 'Color' plot style using 'c' such that the first point uses c(1) to replace the 1 so that the color is [0.916 0 0], etc.?
NOTE: This code is a snippet of something much larger that will likely plot 100's or 1000's of points over time on the same plot. I need the color for each point to be set when it's placed on the plot and then not change as other points are added. (If possible)
I do not think a color map is appropriate as I may plot points at the same X,Y coordinates at different times. Sometimes they will be bright, other times dim.
Just trying to not use a loop which would be relatively straight forward.
Thanks!
To colorize the points (and only the points, not the lines in between), you can use the MarkerFaceColor property of the scatter function (or scatter3 in 3D).
For instance:
scatter(a, b, 'MarkerFaceColor', rgb)
where rgb are RGB triplets, or
scatter(a, b, 'MarkerFaceColor', 'flat', 'CData', c)
with c being a vector of values. In this case the colors are mapped onto the current colormap and the range is controled by caxis.
If you want lines between your points, you can simply use a code like this:
hold on
plot(a, b, '-')
scatter(...)
Best,

Using different intensities of a specific color for contour plots

This question is in reference to visualization of EM clustering(or K-means) of 2D gaussian data. Say, I have displayed 3 clusters obtained from EM in a scatter plot with 3 different colors(say r,g,b) for the data samples of 3 clusters. Now I want to plot elliptical contours on top of this. I don't want the color of each of the three countours vary over entire colorspectrum from r to b. For contours of cluster 1, I want varying intensities of red, for cluster 2, I want varying intensities of blue and same of cluster 3. I have set the number of concentric contours to be 5 and tried passing a Color array as follows, but it did not work.
ColorVec = ['r' ; 'g' ; 'b' ; 'm' ; 'c' ; 'y'; 'b'];
String2RBG = #(C)rem(floor((strfind('kbgcrmyw', C) - 1) * [0.25 0.5 1]), 2);
x = -3:0.1:4;
y = -3:0.1:4;
[X,Y] = meshgrid(x,y);
for k=1:numberOfClusters
Z = mvnpdf([X(:) Y(:)],estimatedMu(k,:),estimatedSigma{k});
Z = reshape(Z,length(y),length(x));
ColorVecConcentricCountours = [String2RBG(ColorVec(k));String2RBG(ColorVec(k))/1.2;String2RBG(ColorVec(k))/1.4;String2RBG(ColorVec(k))/1.6;String2RBG(ColorVec(k))/1.8];
contour(X,Y,Z,5,'color',ColorVecConcentricCountours);hold on;
end
Use of ColorVecConcentricCountours throws an error, but if I give ColorVec(k), it gives a single shade of r, g or b for all 5 contours which is not what I want.
Contour plots are groups of patch objects. Patch objects have an 'EdgeColor' property, which is what sets what we'd call the line color of the contours. You can set the edge colors of all contour objects in the figure with the contourcmap function, but since you want separate control over each of the groups of lines that won't work. What you can do, however, is to address the patch objects themselves and change the edge color of each one separately.
To start, I have written functions called green, cyan, and the rest of the RGB + CYM colors that allow me to use those as colormaps in addition to the built-in ones. The green function looks like this:
function G = green(m)
%GREEN Green Colormap
% GREEN(M) is an M-by-3 matrix colormap for increasing red intensity.
% GREEN, by itself, is the same length as the current figure's
% colormap. If no figure exists, MATLAB creates one.
%
% See also RED, JET, HSV, HOT, PINK, FLAG, COLORMAP, RGBPLOT.
if nargin < 1
m = size(get(gcf,'colormap'),1);
end
G = zeros(m,3);
G(:,2) = (0:(1/(m-1)):1);
You can take a look at the built-in functions to see how this one is similar. To run the code below you'll need a cyan function as well (or change that function call to whatever colormap function you'd like).
Armed with a couple of contour plots put into the same axes and their handles (H1 and H2 below) we can pull out the levels the contours are drawn at with the contour group's LevelList property, yielding a vector of each contour level. Each of the contour patch objects (children of the group) has the level that line was drawn at saved in the patch object's UserData property. We can use the group's LevelList property to make a matrix of colors we want to use, using the colormap function call, then the position of the contour line's level in the LevelList vector is the row of the colormap that we want to use to color that line. Change the EdgeColor of the patch object to that color for each line and we're good to go. Two groups are drawn here to show how to get two contour groups with different colors.
figure()
[C1, H1] = contour(linspace(-50, 0, 50), linspace(-50, 0, 50), peaks(50), 50);
hold on
[C2, H2] = contour(linspace(0, 50, 50), linspace(0, 50, 50), peaks(50), 20);
hold off
axis([-50 50 -50 50]);
levels1 = get(H1, 'LevelList');
cmap1 = green(numel(levels1));
child1 = get(H1, 'Children');
for m = 1:numel(child1)
cmapHere = cmap1(levels1 == get(child1(m), 'UserData'), :);
set(child1(m), 'EdgeColor', cmapHere);
end
levels2 = get(H2, 'LevelList');
cmap2 = cyan(numel(levels2));
child2 = get(H2, 'Children');
for m = 1:numel(child2)
cmapHere = cmap2(levels2 == get(child2(m), 'UserData'), :);
set(child2(m), 'EdgeColor', cmapHere);
end

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)