Scatter plot grouped by row for a 31 x 3 2d array - matlab

I have a 2d array and I want to scatter plot the points grouped by row so that each row has a different symbol. This is my code so far, all the points are the same symbol so I can't tell which points are part of which row.
a = zeros (31,3);
for k = 0:30
y = 5*k
dent = [1 10 10 y]
a(k+1, [1 2 3]) = roots(dent)
end
t = 1:3
gscatter(real(a(:,t)),imag(a(:,t)));

You do not need a loop, you can exploit the gscatter options:
a = zeros (31,3);
for k = 0:30
y = 5*k;
dent = [1 10 10 y];
a(k+1, [1 2 3]) = roots(dent);
end
group = ones(size(a));
group(:,1) = group(:,1).*0;
group(:,3) = group(:,3).*2;
gscatter(real(a(:)),imag(a(:)),group(:),'brg','xo+');
You need an additional vector, group, which contains information on which points in your data-set belong to a specific group. This variable is very versatile, see it's documentation.
In your case, I suggest setting up a matrix that is 0 in the first column, 1 in the second and 2 in the third.
In the gscatter function call, reshape all your matrices into vectors using (:) (because gscatter only works with vectors.
The other two strings passed to gscatter:
'brg'
'xo+'
determine the color and shape of the symbols, respectively. Your plot then looks like this:
EDIT
For those users without access to the gscatter function, this is how it can be done using scatter:
s = 40;
hold on
COLORS='brg';
SYMBOLS='xo+';
for t=1:size(a,2)
scatter(real(a(:,t)),imag(a(:,t)),s,SYMBOLS(t),'MarkerEdgeColor',COLORS(t))
end
hold off
A few things to take note of:
to be used in this way, scatter needs a symbol-size, which was set to s = 40 in this example.
the symbols are stored in a string variable so that the can be called in the loop.
the same is true for the edge colors (face colors could also be specified, check the scatter documentation
when called in a loop, use hold to plot into the same figure (roughly speaking)
This is the output from the standard scatter plot:

Related

Faster way of putting Matrix elements into vectors other than a for loop

Hopefully this will come across correctly. I have 4 clouds/groups of points in a grid array (imagine a 2D space with 4 separate clusters of for example 3x3 grid of points) with each point having an X and Y coordinate. I'd like to write a vector of four points in the form of (X1, Y1, X2, Y2, X3, Y3, X4, Y4) where the number represents each cloud/group. Now I would actually like to write a matrix of all the combinations of the above vector covering all the points, so upper left points in all four groups in the first line, same for the second line, but the top middle point for group 4, etc.
One way to do it is to for-loop over all the variable, which would mean 8 nested for loops (4 for each X coordinate of 4 groups, 4 for each Y coordinate of 4 groups).
Is there a faster way maybe? 4 3x3 groups means 6561 combinations. Going to a larger array in each group, 11x11 for example, would mean 214 million combinations.
I'm trying to parallelize some calculations using these point coordinates, but writing the results in a parfor loop presents it's own set of issues if I was to do it on the points themselves. With a matrix of combinations I could just write the results in another matrix with the same number of rows and write the result of the nth row of point coordinates to the nth row of results.
As I understand, you have 4 groups of 3x3=9 coordinate pairs. You need to draw one pair from each group as one result, and produce all possible such results.
Thus, reducing each of the groups of 9 coordinate pairs to a lookup-table that is indexed with a number from 1 to 9, your problem can be reduced to drawing, with replacement, 4 values from the set 1:9.
It is fairly easy to produce all such combinations. permn is one function that does this (from the File Exchange). But you can actually get these even easier using ndgrid:
ind = 1:9;
[a1,a2,a3,a4] = ndgrid(ind,ind,ind,ind);
ind = [a1(:),a2(:),a3(:),a4(:)];
Each row in ind is the indices into one of your 3x3 grids.
For example, if grid 1 is:
x1 = [0.5,0.7,0.8];
y1 = [4.2,5.7,7.1];
then you can generate the coordinate pairs as follows:
[x1,y1] = meshgrid(x1,y1); % meshgrid is nearly the same as ndgrid...
xy1 = [x1(:),y1(:)];
Now your combination k is:
k = 563;
[xy1(ind(k,1),:), xy2(ind(k,2),:), xy3(ind(k,3),:), xy4(ind(k,4),:)]
You probably want to implement the above using multidimensional arrays rather than x1, x2, x3, etc. Adding indices to variables makes for confusing code that is difficult to extend. For example, for n groups you could write:
n = 4;
ind = 1:9;
ind = repmat({ind},n,1);
[ind{:}] = ndgrid(ind{:});
ind = cellfun(#(m)reshape(m,[],1), ind, 'UniformOutput',false);
ind = [ind{:}]; % ind is now the same as in the block of code above
etc.

Extend a line through 3 points matlab

Im just trying to draw a line through the following points in matlab. Currently the line extends only to the points. I need to to extend and intercept the x axis. The code is below
A = [209.45 198.066 162.759];
B = [1.805 1.637 1.115];
plot(A,B,'*');
axis([0 210 0 2]);
hold on
line(A,B)
hold off
If you want to augment your points with a corresponding y==0 point, I suggest using interp1 to obtain the x-intercept:
A = [209.45 198.066 162.759];
B = [1.805 1.637 1.115];
x0 = interp1(B,A,0,'linear','extrap'); %extrapolate (y,x) at y==0 to get x0
[newA, inds] = sort([x0 A]); %insert x0 where it belongs
newB = [0 B];
newB = newB(inds); %keep the same order with B
plot(A,B,'b*',newA,newB,'b-');
This will use interp1 to perform a linear interpolant, with extrapolation switched on. By interpolating (B,A) pairs, we in effect invert your linear function.
Next we add the (x0,0) point to the data, but since matlab draws lines in the order of the points, we have to sort the vector according to x component. The sorting order is then used to keep the same order in the extended B vector.
Finally the line is plotted. I made use of plot with a linespec of '-' to draw the line in the same command as the points themselves. If it doesn't bother you that the (x0,0) point is also indicated, you can plot both markers and lines together using plot(newA,newB,'*-'); which ensures that the colors match up (in the above code I manually set the same blue colour on both plots).

matlab, how to plot the "root locus"

Given a function (call it sys(s)), we can use matlab: rlocus(sys) to plot the root locus of that function.
However,if we are given a function with a parameter (say b), eg sys(s)=(2s+2+b)/s , how can I use matlab to plot the rlocus(sys) as a function of the parameter b?
Let's say b changes between 1 and 100 with intervals of 1.
b = 1:100;
We need to create axes and hold them, so that we can plot root loci on top of each other.
axes();
hold('on');
Now we need to create a transfer function for each b and plot its root locus.
for idx = 1:length(b)
sys = tf([2 2+b(idx)], [1 0]);
rlocus(sys);
end
This is the resulting plot:
I could not find a vectorized solution, so it takes quite a long time. This took 45 seconds on my computer. If you need to calculate many values, you will need a vectorized solution.
To add a legend, you need to create a cell array to store b values.
legendStr = cell(1, length(b));
Then, inside the for loop you need to convert b values to string and store them in legendStr.
legendStr{idx} = num2str(b(idx));
After the for loop add the legend to the plot.
legend(legendStr)

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)

Adding a curve to Matlab Figure

I have written a program that takes a lot of data and produces graphs.It would be really convenient and save me a lot of time if I could take curves on an existing figure and add their values together to make a single curve. For a simple example lets say I have the following code,
x = [0 1 2 3 4 5];
y = [0 1 2 3 4 5];
z = [4 6 2 8 7 9];
figure
plot(x,y,x,z)
This code will produce a figure with two curves. Without modifying the code or re-running the program, and only working with the figure options I would like to add the curve y + z to the plot. Is this possible? Thanks.
The reason I don't want to add the functionality is the plot code is buried within 8 loops
that calls data from a 4D cell array of file name strings.
If you have the x, y and z variable used in the plot you can just add new lines to the plot with
hold on
plot(x,y+z)
hold off
If you don't have them directly (they were generated in a function, for example, you can always get them from figure with XData, YData properties of line objects.
hline = findobj(gca,'type','line');
x = get(hline,'XData');
y = get(hline,'YData');
X = x{1}; % let's assume that all lines have the same x values.
Y = sum(cell2mat(y));
hold on
plot(X,Y)
hold off