How to overlay a surf plot with a 2D matrix in matlab? - matlab

I have a 3D matrix (300x178x125) describing the X,Y,Z positions of a glacier, which is plotted with the slice command:
clear all
load('glacier.mat')
load('realx.mat')
load('realy.mat')
load('realz.mat')
load('h_deb.mat')
glacier = double(squeeze(glacier));
glacier(glacier==0)=nan;
h = slice(realx,realy,realz,glacier, [], [], 1:size(glacier,1));
set(h, 'EdgeColor','none', 'FaceColor','interp', 'FaceLighting','gouraud')
colorbar;
daspect([0.5 1 0.1])
view(-142,31)
set(gcf, 'color', 'white')
which then looks like this:
I now want to overlay a 2D matrix (300x178) on the surface of the glacier. Thus, I want to apply the color mapping of the 2D image to the glacier surface:
How can I do this?

Related

Matlab: `mesh()` plot with less number of grid

Let's say data is a matrix of size 129 * 129.
by using
mesh(data, 'FaceColor', 'none', 'EdgeColor', 'black')
we get something like
We can find that the grid are quite intense. I would like to have the same figure but with less number of mesh lines, something like
It is of course doable to plot a smaller data, for example data(1:10:end, 1:10:end). But in this way, the plot are not accurate as before anymore.
Another example is plot(..., 'MarkerIndices', ...). This can give you a plot with less number of markers without modifying the plot. https://www.mathworks.com/help/matlab/creating_plots/create-line-plot-with-markers.html
An alternative approach is to use plot3 to plot the mesh lines manually. That way you can plot each line smoothly using all the data points, but not have as many lines.
[X,Y,Z] = peaks(201);
step = 5;
plot3(X(:,1:step:end),Y(:,1:step:end),Z(:,1:step:end),'k')
hold on
plot3(X(1:step:end,:).',Y(1:step:end,:).',Z(1:step:end,:).','k')
hold off
I think your best option would be to create a surf plot with no grid lines (showing a colored surface with the full resolution of your data), then overlay a down-sampled mesh plot. Something like this:
surf(data, 'EdgeColor', 'none');
hold on;
mesh(data(1:10:end, 1:10:end), 'EdgeColor', 'black');
You could also add some transparency to the surf plot to make the mesh visible through it:
surf(data, 'FaceAlpha', 0.7, 'EdgeColor', 'none');
The answer from #David is good. In addition to his approach, we can also replace plot3 with many infinitesimal mesh. The idea is to plot mesh for single vectors many times.
[X,Y,Z] = peaks(201);
tempz = NaN(201, 201);
tempz(1, :) = Z(1, :);
mesh(X, Y, tempz, 'EdgeColor', 'interp');
hold on
% plot x lines
for i = 2:10:201
tempz = NaN(201, 201);
tempz(i, :) = Z(i, :);
mesh(X, Y, tempz, 'EdgeColor', 'interp');
end
% plot y lines
for i = 2:10:201
tempz = NaN(201, 201);
tempz(:, i) = Z(:, i);
mesh(X, Y, tempz, 'EdgeColor', 'interp');
end
The original is
By using the snippet above, it gives
The benefits of this over #David's answer is that you can preserve all of the fancy properties of mesh, for example shading interp etc.

Draw a function from 2D to 1D as an heat map: Matlab

Suppose I have a function w from 2D coordinate space to 1D values, such that
w(a,b) := min(a,b)
I want to represent this function as an heat map in Matlab.
For example, I draw a square on the Cartesian plane with vertices (0,0), (0,1), (1,0), (0,0). Then I colour the region inside the square, by assigning the same colour to any two pairs of points (a,b) and (c,d) if w(a,b)=w(c,d).
Is my understanding of a heatmap correct? If so, how can I achieve this in Matlab?
You can achieve this with surf, which plots a surface which looks like a heatmap when viewed from above. See the commented code for details:
% Define axes points as [0,0.1,0.2,...,1]
ax = 0:0.1:1;
% Make grid of values corresponding to min(x,y)
xy = bsxfun(#min, ax, ax');
% Plot
surf(xy); % Plot surface
view(2); % Look from "above" onto x-y plane
set(gca, 'XTickLabel', ax) % Set x-axis labels
set(gca, 'YTickLabel', ax) % Set y-axis labels
colorbar; % Show colorbar as a legend
Output:
You can extend this by using a custom function if min was just an example.
ax = 0:0.1:1;
% Define function
w = #(a,b) a - exp(b)
% Use custom function inside bsxfun
xy = bsxfun(w, ax, ax');
surf(xy); % ... etc
See the docs for details: https://uk.mathworks.com/help/matlab/ref/bsxfun.html
Also see the docs for pcolor which creates a 2D colour plot so no perspective change is needed, and contourf which outlines regions not all squares.

plot 2D intensity figure in 3D coordinate system

I have a 2D intensity plot, as in this example:
[xx yy] = meshgrid(0:0.1:1, 0:0.1:1);
figure(1)
imagesc(sin(xx)) %(x,y)-plot at z=0
Now, as I have noted in the comment, this plot is in the xy-plane and I have taken z=0. I'd like to plot this in a 3D coordinate system as a function of x and y, but taking z=0. I tried with plot3 in this way, plot3(xx,yy,cos(yy)), but that only plots lines and gives them a curvature which I am not interested in. I'd like only a plane at z=0.
You can use surf to accomplish this. We use the xx and yy meshgrid outputs as the x and y positisions, a matrix of zeros as the z value and sin(xx) as the color. We also remove the edges by setting the EdgeColor to none.
surf(xx, yy, zeros(size(xx)), sin(xx), 'EdgeColor', 'none')

Matlab: How to smooth colors of matrix in plot3( ) function?

I am using plot3 to plot a matrix such that the resultant figure shows different colors for each vector of that matrix:
plot3(Grid.x1(:,:),Grid.x2(:,:),phi(:,:))
How can I smooth the coloring of this plot? Thanks!
You can use varycolor from FileExchange to construct and control a continuous range color spectrum. This way the transition between different lines will seem more natural and proximal lines will have similar colors.
You can read more and see examples usage here http://blogs.mathworks.com/pick/2008/08/15/colors-for-your-multi-line-plots/
Example:
[X,Y,Z] = peaks(128);
% raw plot3()
figure; plot3(X, Y, Z);
% define set equal to line number
ColorSet = varycolor(128);
% smooth plot3()
figure; hold all;
set(gca, 'ColorOrder', ColorSet);
plot3(X, Y, Z); view(3);
Update:
For a continuous 3D plot (i.e. a surface) you can use surfl instead of plot3 and display your data as a 3-D Surface Plot (with Shading). You can additionally apply any colormap on the resulting surface, i.e. gray or ColorSet as above.
surfl(X,Y,Z);
shading interp;
colormap(gray);

MATLAB - 3D Contour Plot (Hydrogen 2p Orbitals)

I've got the following code which works for plotting an x-y slice of the Hydrogen 2pz orbital:
%probability densities
pd_psi_210 = #(r,theta,phi) exp(-r).*(r.^2).*(cos(theta).^2)/(32*pi);
%configuring the range
[x y z] = meshgrid(-10:.1:10,-10:.1:10,-2:.1:2);
[THETA,PHI,R] = cart2sph(x,y,z);
%create array of probability density magnitudes
psi_210_vals = pd_psi_210(R,THETA,PHI);
%plotting
imagesc(psi_210_vals(:,:,1)); %x-y plane
I'd like to plot the 3d contour plot of the orbital. I've tried this (and it doesn't seem to get me what I wanted):
isosurface(psi_210_vals(:,:,:)); %3D contour
How can I get this to work?
You just have to specify the underlying grid, and the level you want. For example:
>> isosurface(-10:.1:10, -10:.1:10, -2:.1:2, psi_210_vals, 0.001);
>> axis equal