How to set an arbitrary direction on a contour plot to perform operation in Matlab - matlab

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.

Related

Contour plot using matlab fails

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)

3D scatter plot with 4D data

I need to plot a 3D figure with each data point colored with the value of a 4th variable using a colormap. Lets say I have 4 variables X,Y,Z and W where W = f(X,Y,Z). I want a 3D plot with X, Y, and Z as the three axis. The statement scatter3(X,Y,Z,'filled','b') gives me a scatter plot in 3D but I want to incorporate the value of Z in the graph by representing the points as an extra parameter (either with different areas :bigger circles for data points with high value of Z and small circles for data points with low value of Z or by plotting the data points with different colors using a colormap). However, I am a novice in MATLAB and dont really know how to proceed. Any help will be highly appreciated.
Thanks in advance!
So just use z for the size vector (4th input) as well as the color vector (5th input):
z = 10*(1:pi/50:10*pi);
y = z.*sin(z/10);
x = z.*cos(z/10);
figure(1)
scatter3(x,y,z,z,z)
view(45,10)
colorbar
The size vector needs to be greater 0, so you may need to adjust your z accordingly.
You are already nearly there... simply use
scatter3(X,Y,Z,s,W);
where s is the point size (scalar, e.g. 3) and W is a vector with your W values.
You might also want to issue an
set(gcf, 'Renderer','OpenGL');
where gcf gets your current figure you are plotting in to significantly increase responsiveness when scattering a lot of data.

matlab - plot inequality in 3d with surf

I want to plot an inequality in 3d using surf. My condition is
0<=x<=1
0<=y<=1
0<=z<=x/(1+y)
I can create a surface plot using the following commands
[x y]=meshgrid(0:0.01:1);
z=x./(1+y);
surf(x,y,z);
This plot gives me regions where z=x/(1+y) but I am interested in regions where 0<=z<=x/(1+y) over all values of x and y. However, I am unable to plot/color the region explicitly. Can you please help.
A similar question has been asked but there was no acceptable answer and my question is also different.
Using isosurface you can show the boundary. There are two options, first create the points
[X,Y,Z]=meshgrid(0:.01:1);
then plot the boundaries in the z-direction (i.e. Z=0 and Z=X./(1+Y))
isosurface(X,Y,Z,Z.*(X./(1+Y)-Z),0)
or plot all the boundaries (including X=0, X=1, Y=0 and Y=1)
isosurface(X,Y,Z,Z.*(X./(1+Y)-Z).*X.*(X-1).*Y.*(Y-1),0)
All you have to do is come up with a function that is constant on any boundary, its value inside or outside is irrelevant as long as it is not zero.

Matlab - Multiple 2D plots along a 3rd dimension

I'm trying to plot many 2D plots (x,y).
But...
each 2D plot is for a constant z.
So really my data is (x,y,z) but not z(x,y), which I believe are the requirements for using the "surf" command.
Could anyone help with this?
Example,
x = velocity
y = drag
I have multiple runs of y(x) for a constant temperature, z.
I just want to plot each (x,y) along a 3rd axis, temperature z.
Ideally I'd also want some sort of contour between the (x,y) plots so I can show the peaks/troughs etc.
Any help would be great.
If the runs are not independent (there is some trend over multiple runs) then it may make sense to use surf. You then need to construct your data such you have an X,Y, and Z - in this case I'd suggest you use the drag measurements as your Z (height).
Assuming that you have all the drag/velocity data in drag and velocity which are both of size [data points x number of runs]:
% construct matrix of run numbers
runs = repmat(1:numruns, [1, datapoints]);
runs = reshape(runs, datapoints, numruns);
% plot and label
surf(runs,velocity,drag);
xlabel('runs')
ylabel('velocity')
zlabel('drag')

turn scatter plot into area plot

I have a 2D scatter plot in MATLAB. Is it possible to interpolate the scatter plot to create an area plot?
If you're simply trying to draw one large filled polygon around your entire set of scattered points, you can use the function CONVHULL to find the convex hull containing your points and the function PATCH to display the convex hull:
x = rand(1,20); %# 20 random x values
y = rand(1,20); %# 20 random y values
hullPoints = convhull(x,y); %# Find the points defining the convex hull
patch(x(hullPoints),y(hullPoints),'r'); %# Plot the convex hull in red
hold on; %# Add to the existing plot
scatter(x,y); %# Plot your scattered points (for comparison)
And here's the resulting figure:
Scatter is generally used to represent data where you can't use a line graph, i.e., where each x might have many different y values, so you can't convert directly to an area graph--it would be meaningless. If your data actually is representable as a line graph, then pass it to area directly.
So I'm not quite sure what you want, but here are some possibilities:
You could create a Voronoi diagram based on your points. This will show a region near your points showing which points are closer to a specific point: voronoi(x,y), or see the help.
You could bucket or quantize your data somehow, making it fit into a grid, and then plot the grid. This could also be considered a histogram, so read up on that.
You could just use larger scatter markers (scatter(x,y,scale) where scale is the same dimensions as x and y).