Color scatter plot in Matlab according to 0 or 1 value - matlab

I populate a grid data=zeros(n,n); with 0's and 1's (could also be thought of as an adjacency grid, if you'd like). I just want to plot the grid with colors according to whether the value at that point is 0 or 1. For example,
scatter(1:n,1:n,data);
It gives me the error:
Error using scatter (line 77)
C must be a single color, a vector the same length as X, or an M-by-3 matrix.
Any suggestions?

you are telling matlab to plot only n points ((1,1), (2,2), ..., (n,n)) where you want actually the cartesian product (1:nX1:n).
Try
[X,Y] = meshgrid(1:n,1:n);
scatter(X(:), Y(:), 10, data(:));

scatter allows you to plot points with different options (color, size, etc) for each point depending on a 'Z' value, but it creates a lot of graphic objects (one for each point).
In your case, you only have 2 subsets of data (among all your points). The points with value 1 and with value 0. So another option is to extract these 2 subsets then plot each subset with each a set of common properties.
%% // prepare test data
n = 10 ;
data=randi([0 1],n); %// create a 10x10 matrix filled with `0` and `1`
%% // extract the 2 subsets
[x0 , y0] = find( data == 0 ) ;
[x1 , y1] = find( data == 1 ) ;
%% // display
figure ; axes('Nextplot','add')
plotOptions = {'LineStyle','none','MarkerEdgeColor','k','MarkerSize',10} ; %// common options for both plots
plot(x0,y0,'o','MarkerFaceColor','r', plotOptions{:} ) %// circle marker, red fill
plot(x1,y1,'d','MarkerFaceColor','g', plotOptions{:} ) %// diamond marker, green fill
This way you have full control on each subset property (you can control the size, color, shape etc...). And you only have 2 graphic objects to handle (instead of n^2).

Related

How to color multiple lines based on their value?

I produced a plot that contains 50 curves and each of them corresponds to a specific value of a parameter called "Jacobi constant", so I have 50 values of jacobi constant stored in array called jacobi_cst_L1:
3.000900891023230
3.000894276927840
3.000887643313580
3.000881028967010
3.000874419173230
3.000867791975870
3.000861196034850
3.000854592397690
3.000847948043080
3.000841330136040
3.000834723697250
3.000828099771820
3.000821489088600
3.000814922863360
3.000808265737810
3.000801695858850
3.000795067776960
3.000788475204760
3.000781845363950
3.000775192199620
3.000768609354090
3.000761928862980
3.000755335851910
3.000748750854930
3.000742084743060
3.000735532899990
3.000728906460450
3.000722309400740
3.000715644446600
3.000709016645110
3.000702431180730
3.000695791284050
3.000689196186970
3.000682547292110
3.000675958537960
3.000669315388860
3.000662738391370
3.000656116141060
3.000649560630930
3.000642857256680
3.000636330415510
3.000629657944820
3.000623060310100
3.000616425935580
3.000609870077710
3.000603171772120
3.000596554947660
3.000590018845460
3.000583342259840
3.000576748353570
I want to use a colormap to color my curves and then show in a lateral bar the legend that show the numerical values corresponding to each color of orbit.
By considering my example image, I would want to add the array of constants in the lateral bar and then to color each curve according the lateral bar.
% Family of 50 planar Lyapunov orbits around L1 in dimensionless unit
fig = figure;
for k1 = 1:(numel(files_L1_L2_Ly_prop)-2)
plot([Ly_orb_filt(1).prop(k1).orbits.x],[Ly_orb_filt(1).prop(k1).orbits.y],...
"Color",my_green*1.1); hold on %"Color",my_green*1.1
colorbar()
end
axis equal
% Plot L1 point
plot(Ly_orb_filt_sys_data(1).x,Ly_orb_filt_sys_data(1).y,'.',...
'color',[0,0,0],'MarkerFaceColor',my_green,'MarkerSize',10);
text(Ly_orb_filt_sys_data(1).x-0.00015,Ly_orb_filt_sys_data(1).y-0.0008,'L_{1}');
%Primary bodies plots
plot(AstroData.mu_SEM_sys -1,0,'.',...
'color',my_blue,'MarkerFaceColor',my_blue,'MarkerSize',20);
text(AstroData.mu_SEM_sys-1,0-0.001,'$Earth + Moon$','Interpreter',"latex");
grid on;
xlabel('$x$','interpreter','latex','fontsize',12);
ylabel('$y$','interpreter','latex','FontSize',12);
How can I color each line based on its Jacobi constant value?
You can use any colour map to produce a series of RGB-triplets for the plotting routines to read (Or create an m-by-3 matrix with elements between 0 and 1 yourself):
n = 10; % Plot 10 lines
x = 1:15;
colour_map = jet(n); % Get colours. parula, hsv, hot etc.
figure;
hold on
for ii = 1:n
% Plot each line individually
plot(x, x+ii, 'Color', colour_map(ii, :))
end
colorbar % Show the colour bar.
Which on R2007b produces:
Note that indexing into a colour map will produce linearly spaced colours, thus you'll need to either interpolate or calculate a lot to get the specific ones you need. Then you can (need to?) modify the resulting colour bar's labels by hand to reflect your input values. I'd simply use parula(50), treat its indices as linspace(jacobi(1), jacobi(end), 50) and then my_colour = interp1(linspace(jacobi(1), jacobi(end), 50), parula(50), jacobi).
So in your code, rather than using "Color",my_green*1.1 for each line, use "Color",my_colour(kl,:), where my_colour is whatever series of RGB triplets you have defined.

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');

Plot vectors with labels in matlab

I have a Nx62 matrix with N 62-D vectors and a NX1 vector with the labels for the vectors. I am trying to plot these vectors with their labels because I want to see the behavior of these classes when plotted in a 62-dimensional space. The vectors belong to three classes according to the labels of a NX1 vector cited before.
How to to that in matlab? when i do plot(vector,classes) the result is very weird to analyse, how to put labels in the graph?
The code i am using to get the labels, vectors and plotting is the following:
%labels is a vector with labels, vectors is a matrix where each line is a vector
[labels,vectors]=libsvmread('features-im1.txt');
when I plot a three dimensional vector is simple
a=[1,2,3]
plot(a)
and then I get the result
but now i have a set of vectors and a set of labels, and i want to see the distribution of them, i want to plot each of these labels but also want to identify their classes. How to do that in matlab?
EDIT: This code is almost working. The problem is the fact that for each vector and class the plot will assign a color. I just want three colors and three labels, one per class.
[class,vector]=libsvmread('features-im1.txt');
%the plot doesn't allow negative and 0 values in the label
class=class+2;
labels = {'class -1','class 0','class 1'};
h = plot(vector);
legend(h,labels{class})
If I understand correctly, this does what you want:
N = 5;
classes = [1 2 3 1 2]; % class of each vector. Size N x 1
colors = {'r', 'g', 'b'}; % you can also define them numerically
matrix = rand(N,62); % example data. Size N x 62
labels = {'class 1','class 2','class 3'}; % class names. Size max(classes) x 1
h = plot(matrix.');
h_first = NaN(1,3); % initialization
for k = 1:max(classes)
ind = find(classes==k);
set(h(ind), 'color', colors{k}) % setting color to all plots of a given class
h_first(k) = h(ind(1)); % remember a handle of each color (for legend)
end
legend(h_first,labels)

How to mark points in a plot that are over a specified value in Matlab?

Say I have a data set with x values of longitude and Y values of 1 to 100. How can I plot the whole data set and represent all Y values over 90 with a different symbol?
Thanks for the help!
The easiest way would be to plot the sets separately, and specify a different symbol for each set i.e.
plot(x(Y<=90),Y(Y<=90),'bx',x(Y>90),Y(Y>90),'bo');
You could also do different colors. The scatter function has the ability to specify a different color for each point with the syntax scatter(x,y,s,c). For your example, you could do:
% make data
rng(0,'twister'); theta = linspace(0,2*pi,150);
x = sin(theta) + 0.75*rand(1,150); x = x*100;
y = cos(theta) + 0.75*rand(1,150); y = y*100;
mask = y>90;
% plot with custom colors for each point
c = zeros(numel(x),3); % matrix of RGB colorspecs
c(mask,:) = repmat([1 0 0],nnz(mask),1); % red
c(~mask,:) = repmat([0 0 1],nnz(~mask),1); % blue
scatter(x,y,10,c,'+');
Or instead of and RGB colorspec matrix, you can index into the current colormap. This allows you to get a nice smooth variation with some value:
scatter(x,y,10,y+x,'o') % x+y is mapped to indexes into default colormap, jet(64)
You can combine this color mapping with the approach of separating the data into two sets to also get different markers. Split the data, plot the first set with scatter as above, hold on, and plot the second set with a different marker. For example,
cv = x+y; % or just y, but this is an interesting example
scatter(x(mask),y(mask),10,cv(mask),'+');
hold on
scatter(x(~mask),y(~mask),10,cv(~mask),'o');
The result is different marker styles, where '+' is used where y>90 and '+' elsewhere, and different colors, where color is determined by mapping the values of cv=x+y onto the current colormap. The idea here is to look at 2 different modes of variations, but you could just use cv=y.

Display values from a matrix in a custom colormap (Matlab)

I want to visualize a matrix based on the values its contain. I have one cell, which contains 11 matrices, each matrix has 4 columns which are x,y,z (the coordinate) and its values. I want to visualize this value, with location x, y, z and define my own colormap based on those values then display the colorbar. I want to use jet as the colormap. I want to use Blue to describe the maximal value and Red as the minimal value on the colormap. The values between maximal and minimal values have a color between red to blue.
This is the code that I already tried:
figure;
hold on
for i=1:length(diameter_lca)
L2 = diameter_lca{i};
dl1 = find(L2(:,4) > minimal_lca & L2(:,4)<2);%diameter 0-2
dl2 = find(L2(:,4) >= 2 & L2(:,4) <= maksimal_lca);%diameter>2-maksimal
x=L2(:,1);
y=L2(:,2);
z=L2(:,3);
plot3(y(dl1),x(dl1),z(dl1),'*','Color','r');
plot3(y(dl2),x(dl2),z(dl2),'*','Color','b');
end
daspect([0.488281 0.488281 0.625000]);
view(3); axis tight
camlight
In those code above, what I do is visualize the values on the 4th column from each matrix then I made a condition which is if the value is between 0-2, I gave red, and when it is between 2-maximal value of the 4th column, I gave blue.
Now, I need to display each value from the 4th column from each matrix in colormap jet without any condition like that.
The easiest would be to use scatter3:
%# make jet colormap from red to blue
cmap = flipud(jet(128));
%# plot values
figure,
scatter3(L(:,1),L(:,2),L(:,3),[],L(:,4),'marker','*')
colormap(cmap)
colorbar