Scatter plot on top of a surface plot has garbled points - matlab

I have the following code that overlays a scatter plot on a surface.
Notice that some of the rounded points are chopped off.
figure
scatter(rand(20,1)*10,...
rand(20,1)*20,...
'o', 'LineWidth',5, ...
'MarkerFaceColor', 'black', ...
'MarkerEdgeColor', 'black')
hold on
[X,Y] = meshgrid(1:0.5:10,1:20);
Z = sin(X) + cos(Y);
surf(X,Y,Z)
view(2)
axis equal square;
Here is the output:

That's actually not a bug. It happens because you use surf which is a 3D plotting tool, and overlay it with small spheres at the height Z=0 generated by the scatter plot. Some of the spheres are cut by the 2d surface manifold at Z=0, some are below the manifold. Choosing view(2) show the part of the scatter plot that is only above the manifold that surf created (or that the surf Z values are <0) .
Change to view(3) and play with the camera angles to see it:
If you want to overlay a scatter plot on the surf data, you can, but you need to take a different path, here are a few suggestions:
add transparency to the surface plot, for example add alpha(0.5) after the surf line in your code and see...
add an artificial Z value to the surf plot so it will not intersect with the scatter plot at Z=0, for example edit the following line to : Z = sin(X) + cos(Y)-pi; ...
plot it differently (first using imagesc then scatter), for example:
[X,Y] = meshgrid(1:0.5:10,1:20);
Z = sin(X) + cos(Y);
imagesc(1:0.5:10,1:20,Z) % the same meshgrid values are used
hold on
scatter(rand(20,1)*10,...
rand(20,1)*20,...
'o', 'LineWidth',5, ...
'MarkerFaceColor', 'black', ...
'MarkerEdgeColor', 'black')
axis equal square;

Related

Matlab scatter plot of z=f(x,y) with values of z on top of the points

I have a Matlab data set from an equation z=f(x,y).
So for each set of (x,y) I have a corresponding value of z. Can I plot the data on a x,y plane where at each location the z-value is printed instead of a dot or a colored dot?
figure;
hold on;
scatter(x,y);
ma = cellstr(num2str(z(:)));
text(x, y + <some_offset>, ma, 'FontSize', 10, 'Color', 'r');

Colorbar height is too large and overlapping figure title

I have a three-dimensional density distribution and create a figure with two subplots. One of the XY plane and one of the YZ plane. For both figures I want a correct colorbar and for some reason the XY plane colorbar is perfect and the YZ plane colorbar is too big and overlaps the figure title. See below for my code and an image of result. EDIT: added functioning example at bottom
%// Data slice in the XY plane
subplot(1,2,1)
h=slice(xi,yi,zi,density,[],[],0);
set(h,'edgecolor','none');
caxis([-8,-2])
colormap(jet);
c = colorbar;
c.Label.String = 'Density in log 10 scale';
view(2)
daspect([1 1 1])
xlabel('X-axis [km]')
ylabel('Y-axis [km]')
zlabel('Z-axis [km]')
title_orbit = ['Mg sputtering in orbital plane at orbit angle ',is];
title({title_orbit,''})
%// Data slice in the YZ plane
subplot(1,2,2)
g=slice(xi,yi,zi,density,0,[],[]);
set(g,'edgecolor','none');
caxis([-8,-2])
colormap(jet);
d = colorbar;
d.Label.String = 'Density in log 10 scale';
view(90,0)
daspect([1 1 1])
xlabel('X-axis [km]')
ylabel('Y-axis [km]')
zlabel('Z-axis [km]')
title_perp = ['Mg sputtering in perpendicular plane at orbit angle ',is];
title({title_perp,''})
For those who want a working example for trying to fix it, see code below.
% Create data with similar structure as original
x = linspace(-100,100,100);
y = linspace(-100,100,100);
z = linspace(-100,100,100);
[xg,yg,zg] = meshgrid(x,y,z);
density = rand([100,100,100]);
% Plot data
figure
subplot(1,2,1)
h=slice(xg,yg,zg,density,[],[],0);
set(h,'edgecolor','none');
colormap(jet);
c = colorbar;
view(2)
daspect([1 1 1])
subplot(1,2,2)
g=slice(xg,yg,zg,density,0,[],[]);
set(g,'edgecolor','none');
colormap(jet);
c = colorbar;
view(90,0)
daspect([1 1 1])
here's a possible workaround, first get the color data from each slice, then use imagesc or imshowto plot that slice data. Using your example:
h=slice(xg,yg,zg,density,0,[],[]);
H=get(h,'CData');
...
g=slice(xg,yg,zg,density,0,[],[]);
G=get(g,'CData');
...
Then open a new figure and use imagesc or imshow:
figure;
subplot(1,2,1)
imshow(H); colormap(jet); colorbar
subplot(1,2,2)
imshow(G); colormap(jet); colorbar

How to let the axes in matlab have different lengths without changing axes limits

I'm trying to plot a 3D surface in Matlab and I want to "compress" the plot a little bit in the z dimension. Now the lengths of x, y and z axes are the same, and the plot looks like a cube. I'd like it to look flatter in the z dimension, without altering the axes limits.
Is there any easy way to achieve this?
Try fiddling with the DataAspectRatio and the PlotBoxAspectRatio properties of the axes, which may also be controlled by the pbaspect and daspect commands, correspondingly.
Example
%// Plot surface
[X, Y] = meshgrid(-10:.1:10, -10:.1:10);
Z = 100 - X .^ 2 - Y .^ 2;
surf(X, Y, Z, 'EdgeColor', 'None')
%// Flatten the z-axis a bit
pbaspect([1 1 .2])
daspect([1 1 50])
Original plot:
Flattened plot:

SLicing a 3-d plot in MATLAB

Suppose in MATLAB I have obtained a 3-D plot, like surf(peaks(20)) how do I get a slice along the plane X=0, and the corresponding 2-D plot?
You can make a contour plot:
data = peaks(50);
figure;
surf(data);
figure;
[C,h] = contour(data, [0 0]);
clabel(C,h);

matlab 3d mesh and line plotting

I need help plotting a spiral helix on a cone. For the helix:
x = tsin(6t)
y = tcos(6t)
z = t/3
...and this helix lies on the cone:
z = sqrt(x^2+y^2)/3
I need to plot the mesh plot of the cone and the 3D line plot of the helix on the same
chart.
I think you want a surface plot of the cone first. Try
[X Y] = meshgrid(-1:.01:1);
Z = sqrt(X.^2 + Y.^2)/3;
Then, plot this surface with the surf function, and set some sort of shading and transparency
surf(X,Y,Z), caxis([-1 1]), shading flat, alpha(.5);
This should make a cone shape (you can play with the colors).
Now for the helix, define the vectors as you did
t = 0:.01:1;
x = t.*cos(6*t);
y = t.*sin(6*t);
z = t/3;
Then do
hold on;
This makes it so any other plotting you do will appear on the same figure.
Then finally,
plot3(x,y,z);