MATLAB - scatter plot of a vector by a matrix? - matlab

I'm very new to Matlab. I'm trying to plot X, where X is an 100x1 vector, against Y, which is an 100x10 matrix. I want the result to be X vs 10 different Y values all in the same graph, different colors for each column. The only way I can think of plotting each column of this matrix is by using the hold command, but then I have to split it up so I get each column individually. Is there an easy way to do this?

Use repmat to expand X to be the same size as Y. Try plotting them with plot(X,Y) and if it looks strange, transpose each one (plot(X',Y')).
You can use linespec arguments to select linestyle, marker style, etc. For example, plot(X,Y,'.') would indicate a point at each vertex with no connecting lines.

You don't need to use repmat, just use plot instead of scatter:
plot(X,Y,'o')
Here's an example:
% some arbitrary data:
X = linspace(-2*pi,2*pi,100).'; % size(X) = 100 1
Y = bsxfun(#plus,sin(X),rand(100,10)); % size(Y) = 100 10
% you only need the next line:
plot(X,Y,'o')
legend('show')

Related

Plotting a Matrix in 3D space in MATLAB without using mesh and surf type of plots

I am not familiar with MATLAB environment and I want to draw a matrix in a way that presents each cell of a matrix as a point in the 3D space.
For example present matrix "A " with the following points in 3D space:
x=1, y=1 Z= 10 , x=1, y=3 Z=27 until reach the point x=3, y=3, z=26.
A =
10 15 27
56 87 2
90 87 26
I do not want to use mesh and surf. I am looking for diagram like plot3 digram.I tried plot3 but it does not show the value of z correctly.
i=1:3;
j=1:3;
plot3(i,j,A(i,j))
In the above figure; 3 values are presented for when x=3 and y=3 however it should present these values for x=1,y=3; x=2,y=3;x=3,y=3
To begin I would recommend you to change your variable names. I'll use x and y instead of i and j. In many language these symbols are more typically used for scalar index rather than full vector indices, and in Matlab they can have a special significance (they are used to represent complex numbers).
That said, in your statement i=1:3; you only generate 3 indices, but you have 9 values to plot in your matrix. These 3 indices have to be repeated (3 times in your case, one for each column). So a proper x and y generation would be:
%% // Manual mesh/coordinate generation
x = bsxfun(#times,1:size(A,1), ones([size(A,2) 1])) ;
x = x(:) ;
y = bsxfun(#times, ones([1 size(A,1)]) , (1:size(A,2)).' ) ;
y = y(:) ;
With that you can use at your convenience scatter3 or plot3:
hscat = scatter3( x, y, A(:) ) ;
hp3 = plot3( x, y, A(:),'Marker','o','LineStyle','none') ;
%// will both produce exactly the same result
Now please consider the fact that the way I generated the x and y coordinate is nothing more than what meshgrid would do for you (or the more dimension generic ndgrid).
For example, in the code below, the 3 plotting methods will produce exactly the same ouput than above, so just take your pick:
%% define a grid
[X,Y] = meshgrid( 1:size(A,1) , 1:size(A,2) ) ;
%% // surface plot (but only points visible, no line)
hsurf = surf(X,Y,A,'Marker','o','LineStyle','none','FaceColor','none') ;
%% // scatter3
hscat = scatter3( X(:), Y(:), A(:) ) ;
%% // plot3
hp3 = plot3( X(:), Y(:), A(:),'Marker','o','LineStyle','none') ;
Why reinvent the wheel when you have one at hand ... meshgrid do the job for you in less code instruction ;-)
To generate the coordinates, you should use ndgrid (or meshgrid, which swaps X and Y.):
[X, Y] = ndgrid(1:3, 1:3);
plot3 is going to connect the input points with a line, so if you want distinct points in your plot, use scatter3:
scatter3(X(:), Y(:), A(:));
(You can also use plot3 in the same way if you want the lines.)

Draw a line with non-Cartesian coordinates in MATLAB

MATLAB's surf command allows you to pass it optional X and Y data that specify non-cartesian x-y components. (they essentially change the basis vectors). I desire to pass similar arguments to a function that will draw a line.
How do I plot a line using a non-cartesian coordinate system?
My apologies if my terminology is a little off. This still might technically be a cartesian space but it wouldn't be square in the sense that one unit in the x-direction is orthogonal to one unit in the y-direction. If you can correct my terminology, I would really appreciate it!
EDIT:
Below better demonstrates what I mean:
The commands:
datA=1:10;
datB=1:10;
X=cosd(8*datA)'*datB;
Y=datA'*log10(datB*3);
Z=ones(size(datA'))*cosd(datB);
XX=X./(1+Z);
YY=Y./(1+Z);
surf(XX,YY,eye(10)); view([0 0 1])
produces the following graph:
Here, the X and Y dimensions are not orthogonal nor equi-spaced. One unit in x could correspond to 5 cm in the x direction but the next one unit in x could correspond to 2 cm in the x direction + 1 cm in the y direction. I desire to replicate this functionality but drawing a line instead of a surf For instance, I'm looking for a function where:
straightLine=[(1:10)' (1:10)'];
my_line(XX,YY,straightLine(:,1),straightLine(:,2))
would produce a line that traced the red squares on the surf graph.
I'm still not certain of what your input data are about, and what you want to plot. However, from how you want to plot it, I can help.
When you call
surf(XX,YY,eye(10)); view([0 0 1]);
and want to get only the "red parts", i.e. the maxima of the function, you are essentially selecting a subset of the XX, YY matrices using the diagonal matrix as indicator. So you could select those points manually, and use plot to plot them as a line:
Xplot = diag(XX);
Yplot = diag(YY);
plot(Xplot,Yplot,'r.-');
The call to diag(XX) will take the diagonal elements of the matrix XX, which is exactly where you'll get the red patches when you use surf with the z data according to eye().
Result:
Also, if you're just trying to do what your example states, then there's no need to use matrices just to take out the diagonal eventually. Here's the same result, using elementwise operations on your input vectors:
datA = 1:10;
datB = 1:10;
X2 = cosd(8*datA).*datB;
Y2 = datA.*log10(datB*3);
Z2 = cosd(datB);
XX2 = X2./(1+Z2);
YY2 = Y2./(1+Z2);
plot(Xplot,Yplot,'rs-',XX2,YY2,'bo--','linewidth',2,'markersize',10);
legend('original','vector')
Result:
Matlab has many built-in function to assist you.
In 2D the easiest way to do this is polar that allows you to make a graph using theta and rho vectors:
theta = linspace(0,2*pi,100);
r = sin(2*theta);
figure(1)
polar(theta, r), grid on
So, you would get this.
There also is pol2cart function that would convert your data into x and y format:
[x,y] = pol2cart(theta,r);
figure(2)
plot(x, y), grid on
This would look slightly different
Then, if we extend this to 3D, you are only left with plot3. So, If you have data like:
theta = linspace(0,10*pi,500);
r = ones(size(theta));
z = linspace(-10,10,500);
you need to use pol2cart with 3 arguments to produce this:
[x,y,z] = pol2cart(theta,r,z);
figure(3)
plot3(x,y,z),grid on
Finally, if you have spherical data, you have sph2cart:
theta = linspace(0,2*pi,100);
phi = linspace(-pi/2,pi/2,100);
rho = sin(2*theta - phi);
[x,y,z] = sph2cart(theta, phi, rho);
figure(4)
plot3(x,y,z),grid on
view([-150 70])
That would look this way

How to display two plot in a specific position with Matlab

Hi to all,
When I run a Matlab code which generate two plot, these are overplotted (the second over the first).
I would like obtain a result as this figure, where the two plots are like in a subplot(211) and subplot(212), the first and the second in two colons, but without using subplot.
It is possible?
UPDATE
I generate this two plot with two subfuncion:
function create_figure(X1, YMatrix1, p)
%CREATE_FIGURE(X1, YMATRIX1)
% X1: vector of x data
% YMATRIX1: matrix of y data
% P: parameters used in legend
% Create figure
figure1 = figure('Name','Acceleration Power vs. Velocity LPF 1st order');
...
and
function create_figure_gamma(X1, YMatrix1, p)
%CREATE_FIGURE_GAMMA(X1, YMATRIX1, P)
% X1: vector of x data
% YMATRIX1: matrix of y data
% P: parameters used in legend
% Create figure
figure1 = figure('Name','gamma trend vs. Velocity');
...
Of course, I can give in output the parameter figure1, writing:
function figure1 = create_figure(X1, YMatrix1, p)
I think that which this parameter is possible set the position of the two plots, but I do not know the procedure respect the generic window size.
You could also set the Units to 'normalized' and enter relative positions for the figures:
set(h1,'Units','normalized');
set(h2,'Units','normalized');
set(h1,'Position',[0.1021 0.1708 0.2917 0.3500]);
set(h2,'Position',[0.4021 0.1700 0.2917 0.3508]);
This way you are independent of the current screen resolution.
This would produce two figures with plots side by side:
x = 0:0.1:2*pi;
y1 = sin(x);
y2 = cos(x);
h1=figure
plot(x,y1);
h2=figure
plot(x,y2);
% x, y, width, height
set(h1,'Position',[20 616,560,420])
set(h2,'Position',[20+560 616,560,420])

plot from data not a function

If you plot
sin(x*y)
you see some lines.
Now if u have all coordinates of all points of these lines and want to plot theme
(connecting dots without using sin(x*y) function), how is possible?
by this codes, i try to obtain coordinates of each 'x'(beta-bar) for each 'lam' and
save roots in a matrix.
clc; clear;
lmin=0.8; lmax=2.5;
bmin=1; bmax=1.5;
lam=linspace(lmin,lmax,100);
for n=length(lam):-1:1
increment=0.001; tolerence=1e-14; xstart=bmax-increment;
x=xstart;
dx=increment;
m=0;
while x > bmin
while dx/x >= tolerence
if sign(f(lam(n),x))*sign(f(lam(n),x-dx))<0
dx=dx/2;
else
x=x-dx;
end
end
m=m+1;
r(m,n)=x;
dx=increment;
x=0.999*x;
end
end
figure
hold on,plot(lam,r(1,:),'b')
plot(lam,r(2,:),'c')
plot(lam,r(3,:),'r')
xlim([lmin,lmax]);ylim([bmin,bmax]),
xlabel('\lambda(\mum)'),ylabel('\beta-bar')
and
function y=f(x,y)
y=sin(4*x*y);
end
what is wrong with it?
how to separately plot each line?
Use plot(X1,Y1,...,Xn,Yn)
See link for more details
http://www.mathworks.com/help/techdoc/ref/plot.html
use the plot() command. From the Matlab docu ('help plot' on the command line):
'PLOT(X,Y) plots vector Y versus vector X. If X or Y is a matrix,
then the vector is plotted versus the rows or columns of the matrix,
whichever line up. If X is a scalar and Y is a vector, disconnected
line objects are created and plotted as discrete points vertically at
X.'
So while plot(sin(X,Y)) used the plot(X) overload of the function, you will use the plot(X,Y) overload.

How can I contour plot a custom function?

I have a custom function which returns either 0 or 1 depending on two given inputs:
function val = myFunction(val1, val2)
% logic to determine if val=1 or val=0
end
How can I create a contour plot of the function over the x,y coordinates generated by the following meshgrid?
meshgrid(0:.5:3, 0:.5:3);
This plot will just simply display where the function is 0 or 1 on the contour map.
If your function myFunction is not designed to handle matrix inputs, then you can use the function ARRAYFUN to apply it to all the corresponding entries of x and y:
[x,y] = meshgrid(0:0.5:3); %# Create a mesh of x and y points
z = arrayfun(#myFunction,x,y); %# Compute z (same size as x and y)
Then you could use the function CONTOUR to generate a contour plot for the above data. Since your z data only has 2 different values, it would probably make sense for you to only plot one contour level (which would be at a value of 0.5, halfway between your two values). You might also want to instead use the function CONTOURF, which produces color-filled contours that will clearly show where the ones and zeroes are:
contourf(x,y,z,1); %# Plots 1 contour level, filling the area on either
%# side with different color
NOTE: Since you are plotting data that only has ones and zeroes, plotting contours may not be the best way to visualize it. I would instead use something like the function IMAGESC, like so:
imagesc(x(1,:),y(:,1),z);
Keep in mind the y-axis in this plot will be reversed relative to the plot generated by CONTOURF.
The following will do it:
function bincontour
clear; clc;
xrange = 0:.5:3;
yrange = 1:.5:5;
[xmesh, ymesh] = meshgrid(xrange, yrange);
z = arrayfun(#myFunction, xmesh, ymesh);
contourf(xrange, yrange, z, 5)
end
function val = myFunction(val1, val2)
val = rand() > 0.5;
end