How to specify a dotted line in plot3? - matlab

I am trying to generate a random rotation matrix R and apply it to a vector. At the end, I have to plot both the original vector and the vector after rotation. The original vector has to be plotted with black dashed line, and the vector after rotation has to be plotted with black dotted line. I have done every step correctly except I can't plot the vector after rotation with dots. MATLAB plots only the beginning and last points of the vector, but not fully. Interestingly if I try 'k--' instead of 'k.' it works correctly. Can somebody show what I am missing here?
% rand(3,1) generates a random 3 by one column vector. We use this u to plot
u=rand(3,1)*2-1;
% plot the origin
plot3(0,0,0,'.k')
% axis setting
axis vis3d
axis off
%%%%% your code starts here %%%%%
% generate a random rotation matrix R
[R,N] = qr(randn(3));
% plot the x axis
plot3([0,1],[0,0],[0,0],'r');
text(1,0,0,'x')
% plot the y axis
plot3([0,0],[0,1],[0,0],'g');
text(0,1,0,'y')
% plot the z axis
plot3([0,0],[0,0],[0,1],'b');
text(0,0,1,'z')
% plot the original vector u
plot3([0,u(1)],[0,u(2)],[0,u(3)], 'k--');
text(u(1),u(2),u(3),['(',num2str(u(1),'%.3f'),',',num2str(u(2),'%.3f'),',',num2str(u(3),'%.3f'),')'])
hold on
% apply rotation and calcuate v plot the vector after rotation v
v = R*u;
% plot the new vector v
plot3([0,v(1)],[0,v(2)],[0,v(3)], 'k.');
text(v(1),v(2),v(3),['(',num2str(v(1),'%.3f'),',',num2str(v(2),'%.3f'),',',num2str(v(3),'%.3f'),')'])
%%%%% your code ends here %%%%%
I replaced 'k.' with ':k' and it worked like a charm. However, I don't have any idea about what is going on. Why didn't 'k.' work which?

The documentation on plot() clearly specifies this:
. Point
-. Dash-dot line
: Dotted line
Thus k. makes only a black dot as marker (i.e. on the exact points you specified as (x,y,z) coordinates), whereas k: makes a dotted line appear from point to point.
The same syntax works for other plotting commands where you can specify line styles, such as plot3D().

Related

How do I plot a discrete array of points say [x1,...xn] on the x axis in MATLAB

Suppose I have a set of points [x1,x2,...,xn] then how do I plot them on the real line? . The reason I am asking is that I want to plot the eigen values of a Gaussian Orthogonal Ensemble along the x axis. So using eig(A) , I get an array of size n(lets say 10) . So I want to plot those 10 points along the x axis. That is I simply want to plot these real numbers on the x-axis. It does not matter if I plot it on say the line y=1 . Given a pen and paper , I would just draw a line and mark them with dots. How do I do this on MATLAB?
Put even simply , I just want to plot [1,2,3,4,5] on the x axis with prominent dots.
So what I would ideally want is a prominent axis and prominent dots on it according to [x1,...,xn] and also display the labels .
Here is a picture
What I have tried is
x=[1,2,3,4]
plot(x,0) or plot(x,1). But it shows just a blank graph. Can anyone help me out with this? I am an absolute noob in MATLAB.
I was expecting the line y=0 or y=1 with dots marking the points (1,0),(2,0),(3,0),(4,0) or (1,1),...,(4,1).
" I was expecting the line y=0 or y=1 with dots marking the points (1,0),(2,0),(3,0),(4,0) or (1,1),...,(4,1)."
The following script will do that:
hold('on') % Do all plots in the same figure
axis([0,5,-0.1 1.1]);grid('on') % Set the axes and turn on the grid
x = 1:4 % x = [1 2 3 4]
plot(x,ones(size(x)),'b') % Line y=1
plot(x,zeros(size(x)),'b') % Line y=0
scatter(x,zeros(size(x)),'MarkerFaceColor','b') % Points: (1,0),(2,0),(3,0),(4,0)
scatter(x,ones(size(x)),'MarkerFaceColor','b') % Points: (1,1),(2,1),(3,1),(4,1)
The result:

Vertical lines for Bode plots in Matlab

I have graphed a Bode plot for my transfer function, and I was wondering if there is some way to insert either horizontal or vertical lines to show a specific value for the gain/phase angle or frequency?
I have found with the following code I can draw a horizontal line on the phase angle graph:
x = linspace(10^-1,10^2,100);
for bleh = 1:length(x)
y(bleh) = -30.9638;
end
bode(num, den)
hold on
plot(x,y)
But this does not seem to apply in the gain graph, nor does my limited knowledge (and only way that makes sense to me) of vertical lines. I tried:
y1 = get(gca,'ylim');
w1 = 1.2;
bode(num, den)
hold on
plot(x,y,[w1 w1],y1)
But I only get the one horizontal line as was done from the above code.
Is this a possibility?
(Using R2017a, if that matters.)
I'm not sure I've understood you question, nevertheless, I propose the following.
When there are more one axes in a figure, as it is the case of the bode diagram, if you want to add something in a specific axes (or in all) you have to specify, in the call to plot the handle of the axes.
So, to add lines in the bode diagram, you have first to identify the handles of the two axes: you can do it in, at least two way:
using the findobj function: ax=findobj(gcf,'type','axes')
extract them as the Children of the figure: ax=get(gcf,'children')
Once you have the handles of the axes, you can get their XLim and YLim that you can use to limit the extent of the line you want to add.
In the following example, I've used the above proposed approach to add two lines in each graph.
The horizontal and vertical lines are added in the middle point of the X and Y axes (problably this point does not have a relevant meaning, but it is ... just an example).
% Define a transfer function
H = tf([1 0.1 7.5],[1 0.12 9 0 0]);
% PLot the bode diagram
bode(H)
% Get the handles of the axes
ax=findobj(gcf,'type','axes')
phase_ax=ax(1)
mag_ax=ax(2)
% Get the X axis limits (it is the same for both the plot
ax_xlim=phase_ax.XLim
% Get the Y axis limits
phase_ylim=phase_ax.YLim
mag_ylim=mag_ax.YLim
%
% Define some points to be used in the plot
% middle point of the X and Y axes of the two plots
%
mid_x=(ax_xlim(1)+ax_xlim(2))/2
mid_phase_y=(phase_ylim(1)+phase_ylim(2))/2
mid_mag_y=(mag_ylim(1)+mag_ylim(2))/2
% Set hold to on to add the line
hold(phase_ax,'on')
% Add a vertical line in the Phase plot
plot(phase_ax,[mid_x mid_x],[phase_ylim(1) phase_ylim(2)])
% Add an horizontal line in the Phase plot
plot(phase_ax,[ax_xlim(1), ax_xlim(2)],[mid_phase_y mid_phase_y])
% Set hold to on to add the line
hold(mag_ax,'on')
% Add a vertical line in the Magnitide plot
plot(mag_ax,[mid_x mid_x],[mag_ylim(1) mag_ylim(2)])
% Add an Horizontal line in the Magnitide plot
plot(mag_ax,[ax_xlim(1), ax_xlim(2)],[mid_mag_y mid_mag_y])
Hope this helps,
Qapla'

Changing perspective of Matlab plots

Say I have a matrix hey 15x15. I want to plot the value of the matrix as a 2D plot for better visualization. But Matlab plots with the convention that origin is in bottom-left corner and positive x is along the left and positive y is along the up direction from origin.
but i want to make my plots such that origin is in top-left corner, +ve x is left and +ve y is down.
So i just used a slight trick.
figure
axis([0 15 -15 0]);
daspect([1,1,1])
hold on
rectangle('Position',[3,-6,2,3],...
'EdgeColor','black',...
'LineWidth',2,...
'FaceColor','cyan')
for i=1:nrows
for j=1:ncolumns
if char(hey(i,j))=='^'
text(j,-i,'^');
elseif char(hey(i,j))=='>'
text(j,-i,'>');
elseif char(hey(i,j))=='v'
text(j,-i,'v');
elseif char(hey(i,j))=='<'
text(j,-i,'<');
end
if obstacle(i,j)==1
text(j,-i,'X');
end
end
end
text(goalY,-goalX,'T');
I made the transformation (x,y)-->(y,-x). But the downside is that the axes are then numbered along y as -1 to -15. However if reader was following above, i only wanted to plot the matrix values and in matrix the y runs +ve downwards from 1 to 15 for my case.
So i want the plot to show +1 thru +15 along y with origin at top-left and x graduated as it is but the values +1 to +15 written at the top of the plot rather than below.
How to do this? In the extreme case, i am alos willing to transfer the matrix hey to another software that can do the nice plot as i want. If any of the two alternatives is possible, please give concrete steps to do it.
EDIT:
After using the helpful methods below, i still have to use a trick like plot (j,i) instead of the innocent plot(i,j). This is because for matrix (i,j) is mapped to graph plot (x,y) as x=j, y=i. Is there a similar workaround? a matrix element is (row #, column #). But in 2D matlab graph, we will denote it's position as (column #, row #). I was just guessing if there was some matlab in-built function to take care of this. like i will give it (row #, column #) but matlab will plot (column #, row #). Is there such a function?
I think axis ij does what you want:
axis ij places the coordinate system origin in the upper left corner. The i-axis is vertical, with values increasing from top to bottom. The j-axis is horizontal with values increasing from left to right.
To locate the x axis on top, change the 'XAxisLocation' of the axes to 'top' (default is 'bottom').
Example:
x = 1:10;
y = x.^2;
plot(x,y)
axis ij
set(gca,'XAxisLocation','top')
Original plot (lines 1-3 of above code):
After axis ij (line 4):
After set(gca,'XAxisLocation','top') (line 5):
If I followed correctly you are looking for the axes XAxisLocation and YDir properties. You can set them to top and reverse respectively to get the output you want. You can also set the XTick property to 1:15 to show every value from 1 to 15.
Example:
clear
clc
%// Create dummy data
[x,y] = meshgrid(1:15,1:15);
u = cos(x).*y;
v = sin(x).*y;
figure
quiver(x,y,u,v)
set(gca,'XAxisLocation','top','XTick',1:15,'YDir','reverse')
hold on
%// I changed the coordinated of the rectangle to fit with the change in
%y-axis.
rectangle('Position',[3,3,2,3],...
'EdgeColor','black',...
'LineWidth',2,...
'FaceColor','cyan')
axis([0 15 0 15])
Which gives the following:

Plotting shaded deviation of a line in Matlab

I would like to plot a line, and in grey-shaded X% deviation of a signal, in MATLAB. Then, I'd plot another signal and see (visually) how much of the second signal is outside the gret-shaded area.
The task I'd like to get help done is the shaded area: similar to the image attached below.
I am aware of similar solutions with errorbar, but I think this is a much clearer plot to visualize.
If for example I had:
x = 0:0.1:10;
y = 1 + sin(x);
What would the 5% grey-shaded plot of y look like? (that area?)
See this answer for an example: MATLAB fill area between lines
Do you have the error of y at each sample in x? Let's assume you have and the upper bound is in variable yu and the lower bound in variable yl. Then you could plot it using:
x = 0:0.1:10;
y = 1 + sin(x);
% I create some yu and yl here, for the example
yu = y+.1;
yl = y-.1;
fill([x fliplr(x)], [yu fliplr(yl)], [.9 .9 .9], 'linestyle', 'none')
hold all
plot(x,y)
fill(X,Y,ColorSpec,...) plots a polygon with edges specified in the first two parameters. You have to fliplr (flip left-right) the arrays, so that it correctly draws the shape of the area to be filled 'in a circle' around it. The [.9 .9 .9] is the colour specification, in this case a light grey. I removed the edge by setting no line, to make it even more similar to your desired plot. One detail: plot the filled area before plotting y, because the last plotted object goes on top of the others.

Plotting a rectangular matrix into a circle

I have generated a rectangular matrix with the azimouth angle changing with rows and the radius changing as you change column. These are meant to represent the relative velocities experienced by a rotating helicopter blade. This produces a matrix called Vmat. I want to plot this to appears in a circle (representing the rotation of the blade)
So far I have tried
[R,T] = meshgrid(r,az);
[x,y] = pol2cart(T,R);
surf(x,y,Vmat(r,az));
which should produce a contoured surface showing velocity as it changes with azimouth angle and radius but it comes up with dimension errors.
I don't mind if it is a 2d contour plot or 3d plot i guess both would be written in a similar way.
Thanks
James
The error is in writing Vmat(r,az), presuming that these are actual values of radius and azimuth, not indexes into your radius and azimuth. If you want to take only a subset of Vmat that's a slightly different matter, but this should work:
[R,T] = meshgrid(r,az); % creates a grid in polar coordinates
[x,y] = pol2cart(T,R); % changes those to cartesian for surf
surf(x,y,Vmat);
Alternatively you could do a contour plot:
h = polar([0 2*pi], [0 max(r)]); % set up polar axes with right scale
delete(h) % remove line
hold on
contour(x,y,Vmat);