I have made a contour plot in matlab using the inbuilt contour function. It plots a group of lines in a figure, each of which represents a contour. I would like to obtain the data points that comprise each of these contours. How can I do this?
So given a contour plot how would I get the actual underlying data points that make up the equation for each contour line. For example, if the contours ended up being straight lines and one of the contour lines went through the origin, I would like to be able to obtain data points that describe this line. e.g. [0 0.1 0.2 0.3 0.4 ; 0 0.25 0.5 0.75 1].
Thanks.
[C,h] = contour(...) returns a contour matrix, C, that contains the x, y coordinates and contour levels for contour lines derived by the low-level contourc function, and a handle, h, to a contourgroup object. The clabel function uses contour matrix C to label the contour lines. ContourMatrix is also a read-only contourgroup property that you can obtain from the returned handle.
If X or Y is irregularly spaced, contour calculates contours using a regularly spaced contour grid, and then transforms the data to X or Y.
By the way, this text was taken from Matlab documentation...
Related
I want two contour plot to show a threshold and I'm using
contourf(X,Y,Z,[-1,-1],'k');
contourf(X,Y,Z,[2,2],'w');
while X and Y a simple meshgrid.
I see that the matrix Z has values above -1 and above 1, so I'm expecting the two lines at -1 and 1 but I see only the first contour lines. What am I doing wrong? Do I get it wrong this property?
Edit: here an example
x = 0:5:180;
y = 0:5:355;
[X,Y] = meshgrid(x,y);
Z = 5*cos(X);
figure(1);## Heading ##
surf(X',Y',Z','EdgeColor','none');
view(2); colorbar;colormap(jet); hold on
contour(X',Y',Z',[-1,-1],'k','LineWidth',1);
contour(X',Y',Z',[2,2],'k','LineWidth',2);
legend('','1','2','Location','northeastoutside');
I saw that if I put the two contour in a new figure, the two are plotted. But when I use surf, I just see the [-1,-1] option.
Many thanks
edit2: using pcolor instead of surf (removing ,'EdgeColor','none') gives me the correct plot...Why? What changes?
What happens is that contourf is not a 3D ploting function, its a 2D plotting function. So when you ask to plot contour lines, it will always plot them at z=0. So your surf plot is "on top of" the contourf for z>0, as you are setting view(2).
Look at the example you gave, with a different view:
You can see both lines here.
pcolor plots a 2D image, not a 3D surface, so it works with pcolor or imagesc.
I am trying to make a contour plot using the following matlab code:
x=linspace(-10,10);
y=linspace(-10,10);
[X,Y]=meshgrid(x,y);
Z=X.^3-Y.^3;
figure
[c,h]=contour(X,Y,Z,[3]);
clabel(c,h)
This gives me the wrong picture actually:
I really don't understand what goes wrong here, because when I do [c,h]=contour(X,Y,Z,[3 0]) for example, it does give me the correct contour plots for the levels 3 and 0, I need help.
If you only give a single number to contour there, it interprets it as the number of contour lines you want and picks the levels automatically. From the docs:
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. For example, to draw contour lines at level k, use contour(Z,[k k]). Specifying the vector v sets the LevelListMode property to manual.
e.g. to get a single contour at "3", you need to do it this way instead:
figure
[c,h]=contour(X,Y,Z,[3,3]);
clabel(c,h)
The fourth argument of contour can be two things.
If it is an array of numbers (more than 1) then its the contour value you want to show. Else, if its a single value, its the amount of contour lines you want to show.
Example:
x=linspace(-10,10);
y=linspace(-10,10);
[X,Y]=meshgrid(x,y);
Z=X.^3-Y.^3;
figure
subplot(121)
[c,h]=contour(X,Y,Z,[10]);
clabel(c,h)
subplot(122)
[c,h]=contour(X,Y,Z,[1000 -1000 50 -70 3 0]);
clabel(c,h)
What I want to do is very simple, I just cannot seem to get MATLAB to do it. I would like to plot contours using my 2D data set.
My data set is large; 2 x 844240. I can do a scatter plot just fine,
scatter(Data(1,:), Data(2,:));
Reading through the forums I found Scatter plot with density in Matlab, where a hisogram was plotted. This would suffice, however, I would like to overlay the plots.
The issue is that they have different axis, my scatter data has an axis of [0 0.01 0 2500]; whereas the histogram is [0 100 0 100].
Is there a way to change the axis values of the histogram without modifying the image?
Thanks!
If I understand correctly, you are using hist3 to construct a histogram and then using imagesc to plot it. You can use the second output argument of hist3 to get the histogram bin centers, and then pass those on to imagesc, e.g.
nBins_x = 100;
nBins_y = 100;
[counts, bin_centers] = hist3(Data, [nBins_x nBins_y]);
x_bin_centers = bin_centers{1};
y_bin_centers = bin_centers{2};
imagesc(x_bin_centers, y_bin_centers, counts)
A couple other notes:
In your case, you will need to transpose your [2 x N] matrix when passing it to hist3, which expects an [N x 2] matrix.
imagesc puts the first axis (which I've been calling the "x" axis) on the vertical axis and the second on the horizontal axis. If you want to flip it, you can use:
imagesc(y_bin_centers, x_bin_centers, counts')
If you want to specify the histogram bins explicitly (e.g. to match your scatterplot) you can specify that in the arguments to hist3:
x_bin_centers = linspace(0, .01, 100);
y_bin_centers = linspace(0, 2500, 100);
counts = hist3(Data, {x_bin_centers, y_bin_centers};
And if you want a contour plot, you can use (note that contour takes the axes arguments in a different order than imagesc):
contour(x_bin_centers, y_bin_centers, counts');
If you are unhappy with the jaggedness of the contours, you may consider using a kernel density estimate instead of a histogram (check out ksdensity) (oops, looks like ksdensity is 1-D only. But there are File Exchange submissions for bivariate kernel density estimation).
I am looking for help for my particular problem.
I have a contour plot created from XYZ data. This plot contains 2 broad peaks with one more intense than the other.
When the most intense peak is aligned with the Y axis, I can perform a fitting of every YZ curve at each X values. I usually do a gaussian fit to plot the peak center on the same graph.
In some cases I need to perform the same fitting but no along the Y axis direction (in this case I just plot YZ scan at every different X values) but along another arbitrary direction.
For the moment the only way I found is the following:
-plot the contour plot and find for the position of the most intense peak
-if the position is not aligned with the Y axis, then rotate all the datas and plot again the contour
-perform the YZ gaussian fit for every X value
- Rotate the resulting XY position to go back to the original plot
-plot the XY position as a line on the original contour plot
this is quite long and requires a lot of memory. i would like ot know if there is a more elegant/faster way.
Thanks for your help
David
I take it you want to extract data from the (x,y,z) data along some arbitrary line in order to make a fit. A contour plot will show only part of the data, the full z(x,y) data can be shown with imagesc etc. Say you want the data along line defined by two points (x1,y1) -> (x2,y2). According to the eq of the line, the line y=a*x+b the slope a is (y2-y1)/(x2-x1) and b=y1-a*x1. For example, I'll select (x,y) coordinates in the following contour:
Create data and end points:
m=peaks(100);
x1=11 ; x2=97;
y1=66; y2=40;
Thus the line parameters are:
a=(y2-y1)/(x2-x1);
b=y1-a*x1;
and the line is:
x=x1:x2;
y=round(a*x+b);
select the proper (x,y) elements using linear indexing:
ind=sub2ind(size(m),y,x)
plot:
subplot(2,1,1)
contour(m,10); hold on
line([x1 x2],[y1 y2],'Color',[1 0 0]);
subplot(2,1,2)
plot(m(ind))
You can now use vec=m(ind) to fit your function.
I've run simulations which have given me data points corresponding to X number of different radii, and Y number of angles each one was evaluated at. This means that I have X times Y data points which I need to plot.
I am currently plotting it in an non-ideal fashion: I am using the x and y axes as the r and theta axes. This means that my data appears as a sinusoidal trend which increases with radius on a Cartesian grid, not the circle which it physically represents. This is how I am currently plotting my data:
surf(r_val, th_val, v_val);
What I wish to do is plot my data on a cylindrical axis, such like that of the function polar(), but in R3 space. I would rather not download a toolbox, or modify the existing polar function; if there is no other solution then I will obviously end up doing this anyways.
Thanks for your help!
G.
Also, I am using Matlab 2012a
EDIT:
r_val = 1x8 vector containing unique radii
th_val = 1x16 vector containing unique angles
v_val = 8x16 matrix containing voltages corresponding to each position
NOTE: (after answered)
The truly ideal solution does not exist to this problem, as Matlab currently supports no true polar axes methods. Resource found here.
You should transform your coordinates to Cartesian coordinates before plotting them. MATLAB has builtin functions for perfroming coordiante transformations. See, for example pol2cart, which transforms polar or cylindrical coordinates to Cartesian coordinates. In your case you would simply use something like:
[x, y] = pol2cart(th_val, r_val);
surf(x, y, v_val);
Edit: Given that th_val and r_val are vectors of differing lengths it is necessary to first create a grid of points before calling pol2cart, along the lines of:
[R, T] = meshgrid(r_val, th_val);
[x, y] = pol2cart(T, R);
surf(x, y, v_val);