Matlab: Explicitly specifying pie graph slice color - matlab

I'm creating a pie graph.
pie([a,b,c,d]);
Is it possible to explicitly change the color of the individual slices?
For example; if I wanted the slices for a and b to always be green and c and d to always be blue, regardless of their size, how would I do that? It seems to me that a color map shades using the size of the slice not necessarily the order in which it was given to the pie function.

The colors of the pie are determined by the axis colormap. So define a matrix with as many rows as the number of pie wedges, and use that as colormap. The first color refers to the first value (a), etc.
For example:
pie([3 2 4 1])
colormap([1 0 0; %// red
0 1 0; %// green
0 0 1; %// blue
.5 .5 .5]) %// grey

Related

Matlab: How to color a region

I am wishing to use Matlab to achieve the following goal:
I have a function that takes in two inputs and gives a real number.
function T = SS(x,y)
%%% some calculation %%%
T = returnval
I want the point (x,y) in the x-y plane to be coloured blue if the return value is equal to 1, green if the return value is equal to 0.5 etc.
I don't know how to approach this.
(the calculation is complicated so it is not obvious what's the relationship between x and y with respect to z. Thus can't write an equation to divide the region then colour accordingly.)
Thanks for helping.
If you can group all your T's into a vector, you can use scatter to make the plot. Then just setup your own colormap. Here's an example:
%// Sample data
[x,y]=meshgrid(0:.1:2);
x=x(:);y=y(:);
T=rand(size(x));
%// Define the colormap
MAP=[1 0 0; %// red
0 1 0; %// green
0 0 1]; %// blue
colormap(MAP) %// apply the colormap
scatter(x,y,[],T) %// make the plot
MAP is a matrix, and each row defines a colour. In this case, there are three rows, so elements with values between 0 and 1/3 will be red, elements with values between 1/3 and 2/3 will be green, and elements between 2/3 and 1 will be blue. In general, the range of T values (i.e. max(T)-min(T)) is evenly divided into each colour defined by MAP.

Produce a 3D stem plot with a custom colormap in MATLAB

I have a matrix (200 x 4) where first 3 values are X, Y and Z data. I want use the fourth column to display each (X,Y,Z) triplet so that it maps to a color.
The fourth column contains values from 0.0 to 1.0 (200 values). I want to map these values with colormap manually and linearly. The smallest value should have blue color and the largest value may have red color.
I know that it is possible with scatter3. However, I want to do using stem3 where I can specify the color manually from colormap.
Is there a way to do this in MATLAB?
That's pretty simple to do. kkuilla posted a very insightful link. To get something started, if you want to have a colour map that varies from blue to red, you know that an image is decomposed into three colours: Red, green and blue.
Therefore, all you would have to do is vary the red and blue channels. Start with a pure blue colour, which is RGB = (0,0,255) where this is mapped to the initial weight of w = 0 and vary this to the end where RGB = (255,0,0) with w = 1. You can very easily do that by linspace. However, colours in a colour map for plotting in MATLAB are normalized so that they're between [0,1], not [0,255]. Also, because a colour map in MATLAB is a matrix of N x 3, where N is the total number of colours you want, all you have to do is:
num_colours = 10;
colourmap = [linspace(0,1,num_colours).' zeros(num_colours,1) linspace(1,0,num_colours).'];
weights = linspace(0,1,num_colours);
num_colours is the total number of colours you would like displayed. I set it to 10 to get you started. weights is something we will need for later, so don't worry about that righ tnow. Essentially, colormap would be the colour map you apply to your data.
However, what is going to be difficult now is that the data that you're plotting has no correlation to the weight of the data itself (or the fourth column of your data). This means that you can't simply use the (X,Y,Z) data to determine what the colour of each plot in your stem is going to look like. Usually for colour maps in MATLAB, the height of the stem is proportional to the colour that is displayed. For the largest Z value in your data, this would naturally be assigned to the colour at the end of your colour map, or red. The smallestZ value in your data would naturally get assigned at the beginning of your colour map, or blue.
If this was the case, you would only need to make one stem call and specify the colour map as the attribute for Color. Because there is no correlation between the height of the Z value and the weight that you're assigning for each data point, you have no choice but to loop through each of your points and determine the closest value between the weight for a point with every weight and ultimately every colour in your colour map, then apply this closest colour to each point in your stem respectively.
We determine the closest point by using the weights vector that was generated above. We can consider each colour as having a mapping from [0,1], and each weight corresponds to the colour in colourmap. Therefore, a weight of 0 is the first colour in the colour map, and that's in the first row. The next weight after this is the second colour, and that's in the second row and so on.... so we simply need to determine where each weight that's in the fourth column of your matrix is closest to for the above weights vector. This will determine which colour we need to select from the colour map to plot the point.
Given that your matrix of 200 x 4 is stored in data, you must specifically do this:
%// Spawn a new figure
figure;
%// Determine the number of points in the dataset
num_points = size(data,1);
%// For each point in the data set
for idx = 1 : num_points
%// Get 4th column element and determine closest colour
w = data(idx,4);
[~,ind] = min(abs(weights-w));
color = colourmap(ind,:);
%// Plot a stem at this point and change the colour of the stem
%// as well as the marker edge colour and face colour
stem3(data(idx,1), data(idx,2), data(idx,3), 'Color', color, ...
'MarkerEdgeColor', color, 'MarkerFaceColor', color);
%// Make sure multiple calls to stem don't clear the plot
hold on;
end
%// Display colour bar to show colours
colormap(colourmap(1:end-1,:));
colorbar('YTickLabel', colourmap);
The last two lines are a bit hackish, but we basically show a colour bar to the right of the plot that tells you how each weight maps to each colour.
Let's test this on some data. I'm going to generate a random 200 x 4 matrix of points and we will use the above code and plot it using stem3:
rng(123123); %// Set seed for reproducibility
data = rand(200,4);
num_colours = 10;
I set the total number of unique colours to 10. Once I have this above data, when I run through the code above, this is the plot I get:
You can use HSV as well. The Z values would correspond to your fourth column. Low Z values are blue and high Z values are red.
I used the site http://colorizer.org/ to work out that blue is H=0.65 and red is H=1. S and V stay the same.
From http://colorizer.org/, I got that a blue colour is H=236, S=100, V=100. Then the H value for blue is H = 235/360 = 0.65 and H=1, S=1, V=1 for red.
num_elem = 200;
c = linspace(0,1,num_elem)'; % // Replace this with the values from your fourth column
% // The equation gives blue (H=0.65) for c=0 and red (H=1) for c = 1
H = 0.65 + ((1-0.65).* c);
S = ones(size(c,1),1);
V = ones(size(c,1),1);
% // You have to convert it to RGB to be compatible with stem3
colourmap = hsv2rgb([H,S,V]);
% // Generate some sample data
theta = linspace(0,2*pi,num_elem)';
X = cos(theta);
Y = sin(theta);
Z = theta;
% // Plot the sample data with the colourmap
figure;
hold on;
for idx=1:num_elem
stem3(X(idx),Y(idx),Z(idx),':*','Color',colourmap(idx,:) ...
,'MarkerEdgeColor',colourmap(idx,:) ...
,'MarkerFaceColor',colourmap(idx,:) ...
,'LineWidth',4 ...
);
end
hold off;
set(gca,'FontSize',36');

Matlab custom colormap with only 3 colors

just want to check if it is possible to make a custom colormap with only 3 colors? (there is no need for gradient).
Example: Data ranges from 0-100,
so 0-33 is one color,
34-67 is another color,
and 68-100 is another color.
Just use a colormap with three rows. Each row defines a color in terms of R, G, B components.
A = randi(100,16,16); %// example data
imagesc(A) %// display matrix as image
colormap([1 0 0; 0 1 0; 0 0 1]) %// apply colormap
colorbar %// show color bar
This defines uniformly spaced thresholds between colors. If you need more control you need to have more than three rows, with some of the colors repeated. For example,
colormap([1 0 0; 1 0 0; 0 1 0; 0 0 1]) %// apply colormap
will define a 50% threshold for first color, 75% for second and 100% for third.
Take this example:
% some matrix with integer values in the range [0,100]
Z = peaks;
Z(:) = round((Z(:)-min(Z(:))) ./ range(Z(:))*100);
% show as image (with scaled color mapping)
image(Z, 'CDataMapping','scaled')
caxis([0 100]) % set axes CLim property
colormap(eye(3)) % set figure Colormap property
colorbar % show colorbar
Note that the colors are scaled to the range [0 100], that range is mapped to the current figure's colormap (which we set to only three colors).
Follow this example: How to create a custom colormap programmatically? but instead of R = linspace(0,t(1),50)' you would use R = ones(50,1)*t(1)
or even simpler:
if colour 1 is t1 = [r1, g1, b1] etc then
map(1:34, :) = repmat(t1, 33, 1)
map(35:68, :) = repmat(t2, (67-34), 1)
etc...
OR
map(1:34, :) = bsxfun(#times, t, ones(33,3))
etc...
Check my answer here
You can use that code and decide to interpolate between values or not, its just 2 lines of the code.
The result image shown in the original post for a GYR cutom colormap.

How show two images in a figure

I need to show two 3D images using one figure, I used alpha( 0.5) but i have problem with colormap
This is my code:
%%%%%%%%%%%%%%%%%%%%%%%%%%% liver 1 %%%%%%%%%%%%%%%%%%%%%%
liver_surf1=isosurface(nii.img(:,end:-1:1,:),0.05);
V=liver_surf1.vertices;
F=liver_surf1.faces;
t=trisurf(F,V(:,1),V(:,2),V(:,3),'facealpha',0.5,'FaceColor',colormap([1 0 0])); % red color
shading flat;
hold on;
%%%%%%%%%%%%%%%%%%%%%%%%%%% liver 2 %%%%%%%%%%%%%%%%%%%%%%
liver_surf=isosurface(nii.img(:,end:-1:1,end:-1:1),0.05);
V2=liver_surf.vertices;
F2=liver_surf.faces;
t2 = trisurf(F2,V2(:,1),V2(:,2),V2(:,3),'facealpha',0.5,'FaceColor',colormap([0 1 0])); % green color
and this is result :
Then problem is that both images colors change to green, if i run separately is ok but i cannot combine both images together. so after i add "shading flat" it becomes like this :
how can i have red and green color together ?
thanks
these are two different liver which should show in an image with transparency because they have intersection.
I'm surprised that code even works (what version of MATLAB do you have?), I would expect trisurf to error. Anyway, colormap is a function that sets the colormap of the image, not of the individual surfaces. You set the colormap to green, all the things will be green.
What you want is to set the colordata, C, to a single value of the same size of your z, then adjust the colormap to give you the right colors. Here's an easy way:
trisurf(F,V(:,1),V(:,2),V(:,3),zeros(size(V(:,3)))); % Cdata = 0
trisurf(F2,V2(:,1),V2(:,2),V2(:,3),,ones(size(V2(:,3)))); %Cdata = 1
colormap([1 0 0; 0 1 0]);
This basically makes two surfaces, one with all color values at zero, the other with all color values at one. The colormap call changes the colormap so it only has two values red (zero) and green (one). (Should also work if you add facealpha etc).

intensity to RGB color convertor, matlab

I have color vector =[0.....1]. I want to convert it to RGB code such that
color_vector =[0.....1] % o for blue, .5 for green and 1 for red
R=255,0,0
G=0,255,0
B=0,0,255
Is there any matlab command(which I could not found) to do it or code.
Another issue is that I want to make my own range for green color (.45-.55) all should be green color.
Basically what you describe is a colormap - but you need to index your color vector for
that.
Incidentally hsv2rgb produces a similar color mapping. But starting from red:
As the hue varies from 0 to 1, the resulting color varies from
red, through yellow, green, cyan, blue and magenta, back to red.
Do you want to linearly interpolate between the colors, for intensity values that are not exactly 0, 0.45-0.55, or 1? If so, you can use real2rgb (on the MATLAB File Exchange), as follows:
I = rand(100, 100); % Input data
cmap = [1 0 0 45; 0 1 0 10; 0 1 0 45; 0 0 1 0]; % Colormap defining the transformation
RGB = real2rgb(I, cmap); % Do the conversion
I use CC and it works well.I can interpolate the colors.