Changing perspective of Matlab plots - matlab

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:

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:

How to specify a dotted line in plot3?

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().

How to fix contourf plot interpolating across NaN region?

I'm trying to create a countourf plot with the region in the bottom left hand corner whited out. Values for the contour are provided at the corner of each rectangle in the below image and all other points on the mesh have a value of NaN.
I want to know how to stop the countourf plot from drawing the triangular section at the top right of the white square, i.e. how do I stop it from interpolating across these two values.
End game: I would like a complete white rectangle on the bottom left, not a chamfered rectangle.
You are getting that triangle because on that specific square your data looks something like:
[1 2 ;...
NaN 3]
And that is a completely valid upper right triangle to contour.
So you can interpolate your data to get more resolution and make that triangle smaller. Or you could just use patch to add a white square at the desired position.
data=rand(8);
data(1:4,1:4)=NaN;
contourf(data)
hold on;
patch([1 1 5 5],[1 5 5 1],'w')
It looks like seven squares a side, so we can set
x = 1:7;
[XX,YY] = meshgrid(x); % create x,y grid for the square
ZZ = nan(7); % create number grid for the square
ZZ(1:3,1:3)=ones(3); % set the lower 3x3 to 1
figure;
hold on % hold your plot
plot()% your contour
imagesc(XX,YY,ZZ); % Or similar
This is the outline, I can't determine what exact plotting function you need since you didn't show your code. In general, the idea is to create a grid as large as that of your contour plot, and set the lower left square to 1, thus white, leaving the rest NaN, thus not plotted.

How to merge different plot but same y axis in matlab

I'm always see this kind of graph in XRD plot:
and i'm wondering how they do that?, if you have different XRD plot and assuming having the same y axis, can matlab do this? thanks.
Here is a way to do it.You can customize it as you want, but this should hopefully get you going.
First create an axes and change its position/size inside the figure, shifting it upward to make room for the 2nd axes as well as removing the x and y labels that you don't want. Then create a 2nd axes with specified position/size to make it fit below the 1st one.
Sample code:
clear
clc
%// Generate dummy data
x = 1:2:100;
y1 = rand(1,numel(x));
figure;
%// Make an axes and set its position
haxes1 = axes('Position',[.1 .1 .8 .7],'Color',[1 1 1])
%// Plot 1st curve
plot(x,y1,'Parent',haxes1)
%// Remove box and labels
box off
set(gca,'XTickLabel','','XTick',[],'YTick',[])
hold on
%// Get current axes position. You set it so you could get the parameters
%// directly as well.
axes1Pos = get(gca,'Position');
%// Shift 1st axes upward
set(gca,'Position',[axes1Pos(1) 2.6*axes1Pos(2) axes1Pos(3) axes1Pos(4)])
%// Change the poisition/size of the 2nd axes to fit below the 1st one
haxes2 = axes('Position',[axes1Pos(1) axes1Pos(2)/2.5 axes1Pos(3) axes1Pos(4)/2.5]) ;
%// Use linspace to generate colored points to use with scatter.
c = linspace(1,10,length(x));
%// Add 2nd plot and keep only x label
scatter(x,rand(1,numel(x)),40,c,'filled')
set(gca,'YTick',[])
box off
%// Place a ylabel for both axes
text(-4, 1.7,'Super nice y label','rotation',90,'FontSize',16,'HorizontalAlignment','center')
Sample output:
There are other ways to do this as well.
Hope that helps!

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.