Related
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])
I want to draw a contour plot for 3D data.
I have a force in x,y,z directions I want to plot the contour3 for that
the dimensions of the Fx = 21x21X21 same for Fy and Fz
I am finding force = f*vector(x,y,z)
Then
Fx(x,y,z) = force(1)
Fy(x,y,z) = force(2)
Fz(x,y,z) = force(3)
I did the following but it is not working with me ?? why and how can I plot that
FS = sqrt(Fx.^2 + Fy.^2 + Fz.^2);
x = -10:1:10;
[X,Y] = meshgrid(x);
for i=1:length(FS)
for j = 1:length(FS)
for k=1:length(FS)
contour3(X,Y,FS(i,j,k),10)
hold on
end
end
end
This is the error I am getting
Error using contour3 (line 129)
When Z is a vector, X and Y must also be vectors.
Your problem is that FS is not the same shape as X and Y.
Lets illustrate with a simple example:
X=[1 1 1
2 2 2
3 3 3];
Y=[1 2 3
1 2 3
1 2 3];
Z=[ 2 4 5 1 2 5 5 1 2];
Your data is probably something like this. How does Matlab knows which Z entry corresponds to which X,Y position? He doesnt, and thats why he tells you When Z is a vector, X and Y must also be vectors.
You could solve this by doing reshape(FS,size(X,1),size(X,2)) and will probably work in your case, but you need to be careful. In your example, X and Y don't seem programatically related to FS in any way. To have a meaningful contour plot, you need to make sure that FS(ii,jj,k)[ 1 ] corresponds to X(ii,jj), else your contour plot would not make sense.
Generally you'd want to plot the result of FS against the variables your are using to compute it, such as ii, jj or k, however, I dont know how these look like so I will stop my explanation here.
[ 1 ]: DO NOT CALL VARIABLES i and j IN MATLAB!
I'm not sure if this solution is what you want.
Your problem is that contour and contour3 are plots to represent scalar field in 2D objects. Note that ball is 2D object - every single point is defined by angles theta and phi - even it is an object in "space" not in "plane".
For representation of vector fields there is quiver, quiver3, streamslice and streamline functions.
If you want to use contour plot, you have to transform your data from vector field to scalar field. So your data in form F = f(x,y,z) must be transformed to form of H = f(x,y). In that case H is MxN matrix, x and y are Mx1 and Nx1 vectors, respectively. Then contour3(x,y,H) will work resulting in so-called 3D graph.
If you rely on vector field You have to specify 6 vectors/matrices of the same size of corresponding x, y, z coordinates and Fx, Fy, Fz vector values.
In that case quiver3(x,y,z,Fx,Fy,Fz) will work resulting in 6D graph. Use it wisely!
As I comment the Ander's answer, you can use colourspace to get more dimensions, so You can create 5D or, theoretically, 6D, because you have x, y, z coordinates for position and R, G, B coordinates for the values. I'd recommend using static (x,y,R,G,B) for 5D graph and animated (x,y,t,R,G,B) for 6D. Use it wisely!
In the example I show all approaches mentioned above. i chose gravity field and calculate the plane 0.25 units below the centre of gravity.
Assume a force field defined in polar coordinates as F=-r/r^3; F=1/r^2.
Here both x and yare in range of -1;1 and same size N.
F is the MxMx3 matrix where F(ii,jj) is force vector corresponding to x(ii) and y(jj).
Matrix H(ii,jj) is the norm of F(ii,jj) and X, Y and Z are matrices of coordinates.
Last command ensures that F values are in (-1;1) range. The F./2+0.5 moves values of F so they fit into RGB range. The colour meaning will be:
black for (-1,-1,-1),
red for (1,-1,-1),
grey for (0,0,0)
Un-comment the type of plot You want to see. For quiver use resolution of 0.1, for other cases use 0.01.
clear all,close all
% Definition of coordinates
resolution=0.1;
x=-1:resolution:1;
y=x;
z=-.25;
%definition of matrices
F=zeros([max(size(x))*[1 1],3]); % matrix of the force
X=zeros(max(size(x))*[1 1]); % X coordinates for quiver3
Y=X; % Y coordinates for quiver3
Z=X+z; % Z coordinates for quiver3
% Force F in polar coordinates
% F=-1/r^2
% spherical -> cartesian transformation
for ii=1:max(size(x))
for jj=1:max(size(y))
% temporary variables for transformations
xyz=sqrt(x(ii)^2+y(jj)^2+z^2);
xy= sqrt(x(ii)^2+y(jj)^2);
sinarc=sin(acos(z/xyz));
%filling the quiver3 matrices
X(ii,jj)=x(ii);
Y(ii,jj)=y(jj);
F(ii,jj,3)=-z/xyz^2;
if xy~=0 % 0/0 error for x=y=0
F(ii,jj,2)=-y(jj)/xyz/xy*sinarc;
F(ii,jj,1)=-x(ii)/xyz/xy*sinarc;
end
H(ii,jj)=sqrt(F(ii,jj,1)^2+F(ii,jj,2)^2+F(ii,jj,3)^2);
end
end
F=F./max(max(max(F)));
% quiver3(X,Y,Z,F(:,:,1),F(:,:,2),F(:,:,3));
% image(x,y,F./2+0.5),set(gca,'ydir','normal');
% surf(x,y,Z,F./2+.5,'linestyle','none')
% surf(x,y,H,'linestyle','none')
surfc(x,y,H,'linestyle','none')
% contour3(x,y,H,15)
I am a new MATLAB user and I am trying to plot a function:
function [ uncertainty ] = uncertain(s1, s2, p)
%UNCERTAIN calculates the measurement uncertainty of a triangulation
% provide two coordinates of known stations and a target coordinate
% of another point, then you get the uncertainty
[theta1, dist1] = cart2pol(p(1)-s1(1), p(2)-s1(2));
[theta2, dist2] = cart2pol(p(1)-s1(1), p(2)-s2(2));
theta=abs(pi-theta2-theta1);
uncertainty = dist1*dist2/abs(sin(theta));
end
called with:
uncertain([0 0],[8 0],[4 4])
I get a single result.
But i want a whole surface and called:
x=-2:.1:10;
y=-2:.1:10;
z = uncertain([0 0],[8 0],[x y]);
mesh(x,y,z)
I get the error: "Z must be a matrix, not a scalar or vector."
How can I modify my code so that my function draws a surface?
Thanks in advance.
Ralf.
First I think there's a mistake in your function: your [theta2, dist2] = cart2pol(p(1)-s1(1), p(2)-s2(2)); should have th first s1 being a s2.
Next, to get a vector answer out for your vector inputs, you have to change your p(i) (which selects the ith element of p) to p(i,:), which will select the first ith row of p.
After that, you change multiplication (*) to element-wise multiplication (.*).
In summary:
function [ uncertainty ] = uncertain(s1, s2, p)
%UNCERTAIN calculates the measurement uncertainty of a triangulation
% provide two coordinates of known stations and a target coordinate
% of another point, then you get the uncertainty
% target coordinates p are 2xn
% output uncertainty is 1xn
[theta1, dist1] = cart2pol(p(1,:)-s1(1), p(2,:)-s1(2));
[theta2, dist2] = cart2pol(p(1,:)-s2(1), p(2,:)-s2(2));
theta=abs(pi-theta2-theta1);
uncertainty = dist1.*dist2./abs(sin(theta));
end
The only changes are p(i) -> p(i,:), and *->.* and /->./.
To get a surface, you use meshgrid to get all sets of (x,y) coordinates in a grid, flatten them into a 2xn matrix for uncertain, and then expand them back out to the grid to plot. Example:
x=-2:.1:10; % 121 elements
y=-2:.1:10; % 121 elements
[xs,ys]=meshgrid(x,y); % xs and ys are each 121 x 121
zs = uncertain([0 0],[8 0],[xs(:) ys(:)]'); %get zs, being 1x(121*121) ie 1x14641
% Reshape zs to be 121x121 in order to plot with mesh
mesh(xs,ys,reshape(zs,size(xs)))
Note: you'll get lots of really big numbers because when theta is 0 or pi (or very nearly) because then you're dividing by (almost) 0.
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
for an implicit equation(name it "y") of lambda and beta-bar which is plotted with "ezplot" command, i know it is possible that by a root finding algorithm like "bisection method", i can find solutions of beta-bar for each increment of lambda. but how to build such an algorithm to obtain the lines correctly.
(i think solutions of beta-bar should lie in an n*m matrix)
would you in general show the methods of plotting such problem? thanks.
one of my reasons is discontinuity of "ezplot" command for my equation.
ok here is my pic:
alt text http://www.mojoimage.com/free-image-hosting-view-05.php?id=5039TE-beta-bar-L-n2-.png
or
http://www.mojoimage.com/free-image-hosting-05/5039TE-beta-bar-L-n2-.pngFree Image Hosting
and my code (in short):
h=ezplot('f1',[0.8,1.8,0.7,1.0]);
and in another m.file
function y=f1(lambda,betab)
n1=1.5; n2=1; z0=120*pi;
d1=1; d2=1; a=1;
k0=2*pi/lambda;
u= sqrt(n1^2-betab^2);
wb= sqrt(n2^2-betab^2);
uu=k0*u*d1;
wwb=k0*wb*d2 ;
z1=z0/u; z1_b=z1/z0;
a0_b=tan(wwb)/u+tan(uu)/wb;
b0_b=(1/u^2-1/wb^2)*tan(uu)*tan(wwb);
c0_b=1/(u*wb)*(tan(uu)/u+tan(wwb)/wb);
uu0= k0*u*a; m=0;
y=(a0_b*z1_b^2+c0_b)+(a0_b*z1_b^2-c0_b)*...
cos(2*uu0+m*pi)+b0_b*z1_b*sin(2*uu0+m*pi);
end
fzero cant find roots; it says "Function value must be real and finite".
anyway, is it possible to eliminate discontinuity and only plot real zeros of y?
heretofore,for another function (namely fTE), which is :
function y=fTE(lambda,betab,s)
m=s;
n1=1.5; n2=1;
d1=1; d2=1; a=1;
z0=120*pi;
k0=2*pi/lambda;
u = sqrt(n1^2-betab^2);
w = sqrt(betab^2-n2^2);
U = k0*u*d1;
W = k0*w*d2 ;
z1 = z0/u; z1_b = z1/z0;
a0_b = tanh(W)/u-tan(U)/w;
b0_b = (1/u^2+1/w^2)*tan(U)*tanh(W);
c0_b = -(tan(U)/u+tanh(W)/w)/(u*w);
U0 = k0*u*a;
y = (a0_b*z1_b^2+c0_b)+(a0_b*z1_b^2-c0_b)*cos(2*U0+m*pi)...
+ b0_b*z1_b*sin(2*U0+m*pi);
end
i'd plotted real zeros of "y" by these codes:
s=0; % s=0 for even modes and s=1 for odd modes.
lmin=0.8; lmax=1.8;
bmin=1; bmax=1.5;
lam=linspace(lmin,lmax,1000);
for n=1:length(lam)
increment=0.001; tolerence=1e-14; xstart=bmax-increment;
x=xstart;
dx=increment;
m=0;
while x > bmin
while dx/x >= tolerence
if fTE(lam(n),x,s)*fTE(lam(n),x-dx,s)<0
dx=dx/2;
else
x=x-dx;
end
end
if abs(real(fTE(lam(n),x,s))) < 1e-6 %because of discontinuity some answers are not correct.%
m=m+1;
r(n,m)=x;
end
dx=increment;
x=0.99*x;
end
end
figure
hold on,plot(lam,r(:,1),'k'),plot(lam,r(:,2),'c'),plot(lam,r(:,3),'m'),
xlim([lmin,lmax]);ylim([1,1.5]),
xlabel('\lambda(\mum)'),ylabel('\beta-bar')
you see i use matrix to save data for this plot.
![alt text][2]
because here lines start from left(axis) to rigth. but if the first line(upper) starts someplace from up to rigth(for the first figure and f1 function), then i dont know how to use matrix. lets improve this method.
[2]: http://www.mojoimage.com/free-image-hosting-05/2812untitled.pngFree Image Hosting
Sometimes EZPLOT will display discontinuities because there really are discontinuities or some form of complicated behavior of the function occurring there. You can see this by generating your plot in an alternative way using the CONTOUR function.
You should first modify your f1 function by replacing the arithmetic operators (*, /, and ^) with their element-wise equivalents (.*, ./, and .^) so that f1 can accept matrix inputs for lambda and betab. Then, run the code below:
lambda = linspace(0.8,1.8,500); %# Create a vector of 500 lambda values
betab = linspace(0.7,1,500); %# Create a vector of 500 betab values
[L,B] = meshgrid(lambda,betab); %# Create 2-D grids of values
y = f1(L,B); %# Evaluate f1 at every point in the grid
[c,h] = contour(L,B,y,[0 0]); %# Plot contour lines for the value 0
set(h,'Color','b'); %# Change the lines to blue
xlabel('\lambda'); %# Add an x label
ylabel('$\overline{\beta}$','Interpreter','latex'); %# Add a y label
title('y = 0'); %# Add a title
And you should see the following plot:
Notice that there are now additional lines in the plot that did not appear when using EZPLOT, and these lines are very jagged. You can zoom in on the crossing at the top left and make a plot using SURF to get an idea of what's going on:
lambda = linspace(0.85,0.95,100); %# Some new lambda values
betab = linspace(0.95,1,100); %# Some new betab values
[L,B] = meshgrid(lambda,betab); %# Create 2-D grids of values
y = f1(L,B); %# Evaluate f1 at every point in the grid
surf(L,B,y); %# Make a 3-D surface plot of y
axis([0.85 0.95 0.95 1 -5000 5000]); %# Change the axes limits
xlabel('\lambda'); %# Add an x label
ylabel('$\overline{\beta}$','Interpreter','latex'); %# Add a y label
zlabel('y'); %# Add a z label
Notice that there is a lot of high-frequency periodic activity going on along those additional lines, which is why they look so jagged in the contour plot. This is also why a very general utility like EZPLOT was displaying a break in the lines there, since it really isn't designed to handle specific cases of complicated and poorly behaved functions.
EDIT: (response to comments)
These additional lines may not be true zero crossings, although it is difficult to tell from the SURF plot. There may be a discontinuity at those lines, where the function shoots off to -Inf on one side of the line and Inf on the other side of the line. When rendering the surface or computing the contour, these points on either side of the line may be mistakenly connected, giving the false appearance of a zero crossing along the line.
If you want to find a zero crossing given a value of lambda, you can try using the function FZERO along with an anonymous function to turn your function of two variables f1 into a function of one variable fcn:
lambda_zero = 1.5; %# The value of lambda at the zero crossing
fcn = #(x) f1(lambda_zero,x); %# A function of one variable (lambda is fixed)
betab_zero = fzero(fcn,0.94); %# Find the value of betab at the zero crossing,
%# using 0.94 as an initial guess