Extracting data from contour plot - matlab

I want to extract the data in a contour plot that I have, especially the maximum number of (x,y) co-ordinates that make up the entire contour.
I have written the following code:
[c,h] = contour(xgrid,ygrid,Z,[4e-6,4e-6],'EdgeColor',[1 0 0],'LineWidth',2);
Any help is appreciated. Thank you.

if you call contour with 2 outputs, with the following format :
[M,h] = contour( )
h is the handle to modify contour properties, and
M contains the points you are looking for.
M has the following format
Z1, x_1_1, x_1_2, ..., x_1_N1, Z2, x_2_1, x_2_2, ..., x_2_N2, Z3, ...
N1, y_1_1, y_1_2, ..., y_1_N1, N2, y_2_1, y_2_2, ..., y_2_N2, N3, ...
Zi : height of i-th contour line
Ni : Amount points in i-th contour line
(xij, yij) : The points, coordinates of points i-th contour line and j ranges from 1 to Ni
all details explained here
https://uk.mathworks.com/help/matlab/ref/contour.html?s_tid=srchtitle_contour_1#f19-795863_sep_mw_d9e727e2-79e4-4cf6-bfaf-431a164d82b0

Related

How to group the green contour and the yellow contour?

I'm using imcontour in MATLAB to get the contour of some image. The resulting image is as follow. Is there any way that I can pick out the green contour together as a group, and the yellow contour together as a group?
fig.1
The good news is that your data are already grouped. Assuming you have an image/matrix I and you are doing something like imcontour(I, 2), you have just to use [C, h] = imcontour(I, 2).
C is a ContourMatrix, which contains (type help clabel) the "contour line definitions, returned as a two-row matrix. Each contour line in the plot has an associated definition. If there are a total of N contour lines in the plot, then the contour matrix consists of N definitions (N=2 in your example):
C = [C(1) C(2)...C(k)...C(N)]
Each contour line definition follows this pattern:
C(k) = [level x(1) x(2) ... x(numxy)
numxy y(1) y(2) ... y(numxy) ]

Contours in Matlab/Octave

I am having some trouble understanding contours.
What I have understood so far is that contours are a way to represent a 3d figure in a 2d plane. It does so by plotting a function of 2 variables as curves along which the function has same value.
Now if I do:
z=[1 4; 10 7];
contour(z);
I get this:
I read the documentation and it says:
contour(Z) draws a contour plot of matrix Z, where Z is interpreted as
heights with respect to the x-y plane. Z must be at least a 2-by-2
matrix that contains at least two different values. The x values
correspond to the column indices of Z and the y values correspond to
the row indices of Z. The contour levels are chosen automatically.
Thus for x=1,y=1: z=1, x=2,y=1: z=4 and so on. However I can't understand how to interpret this as the contour plot shown above.
And if I write:
contour(X1, X2, vals, [0.5 0.5], 'b'); where X1, X2 and vals are equal sized matrices and vals is a matrix of only 0s and 1s. I can't understand what does the argument [0.5 0.5] do. I read the documentation which states:
contour(Z,v) draws a contour plot of matrix Z with contour lines at
the data values specified in the monotonically increasing vector v. To
display a single contour line at a particular value, define v as a
two-element vector with both elements equal to the desired contour
level.
and I am unable to understand this statement.
The problem of the first contour is that there are just 4 values. Try something like
x = 0:0.1:10;
y = 0:0.1:10;
z = sin(x') * cos(y);
contour(z)
For the second thing, this means that if you want to see just particular contours, input them as vector v. In the example above:
contour(z, [0.1, 0.2, 0.3])
will show contour lines of 0.1, 0.2 and 0.3.
To have a single contour line, you can't have just (z, 0) but require (z, [0,0])

MATLAB - scatter plot of a vector by a matrix?

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')

drawing 3d contour plot from 3d vector

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)

How do I plot my function to a mesh

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.