Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I mark (or) shade the area below the graph of Surface plot in Matlab?

Tags:

matlab

I am trying to plot a 3D surface graph for the following equation t_t <= (xi_i - xi_j) . sqrt(rho). I have included my code. But I would like to mark or shade the area under the graph of this surface plot. How do I solve it?

[X,Y] = meshgrid(1:0.5:10,1:20);

Z = X.* sqrt(Y);

figure;

colormap(jet)

surf(X,Y,Z) 

colorbar

xlabel('Distance between two spatial points \xi_i & \xi_j (\xi_i - \xi_j)');

ylabel('Density(\rho)');

zlabel('Transmission Delay (t_t)');

enter image description here

like image 271
hks hks Avatar asked May 29 '19 11:05

hks hks


2 Answers

You can add the extra surfaces by building up a new set of matrices to pass to surf, with a few different options based on how you want the results to look...

Option #1: Fill the sides, one surface object:

If you want to just fill in the sides, you can add a new row and column on each side of your matrices like so:

[R, C] = size(Z);
Xfill = [nan X(1, :) nan; X(:, [1 1:C C]); nan X(R, :) nan];
Yfill = [nan Y(1, :) nan; Y(:, [1 1:C C]); nan Y(R, :) nan];
Zfill = [nan zeros(1, C) nan; zeros(R, 1) Z zeros(R, 1); nan zeros(1, C) nan];

surf(Xfill, Yfill, Zfill);
view(-120, 30);

This allows you to plot the surface and sides with a single call to surf, with this result:

enter image description here


Option #2: Fill the sides and bottom, one surface object:

If you would also like to fill in the bottom of the shape, you can wrap the surface around and under itself by adding new columns and then add a new row at the top and bottom to close the ends:

[R, C] = size(Z);
Xfill = [X(1, 1:C) nan(1, C+1); ...  % Close top
         X flip(X, 2) X(:, 1); ...   % Flip data and connect to other side
         X(R, 1:C) nan(1, C+1)];     % Close bottom
Yfill = [Y(1, 1:C) nan(1, C+1); ...
         Y flip(Y, 2) Y(:, 1); ...
         Y(R, 1:C) nan(1, C+1)];
Zfill = [zeros(1, C) nan(1, C+1); ...
         Z zeros(R, C) Z(:, 1); ...
         zeros(1, C) nan(1, C+1)];

surf(Xfill, Yfill, Zfill);
view(-120, -20);

Again, you can plot the entire closed surface with a single call to surf. Here's the view from the underside, showing the closed bottom:

enter image description here


Option #3: Add a separate surface object for the sides:

When plotting everything as one object, you're limited if you want to render the sides differently than the top. Making the sides separate objects like Ander does (using patch or a separate call to surf) will give you more control over how they are colored relative to the top surface. To make a single surface object for all four of your sides, you can extract the entries around the edges of your matrices and replicate them as needed:

[R, C] = size(Z);
Xside = [1; 1]*[X(1, :) ...           % Get first row
                X(2:R, C).' ...       % Get last column, without first row
                X(R, (C-1):-1:1) ...  % Get last row, without last column, flipped
                X((R-1):-1:1, 1).'];  % Get first column, without last row, flipped
Yside = [1; 1]*[Y(1, :) ...
                Y(2:R, C).' ....
                Y(R, (C-1):-1:1) ...
                Y((R-1):-1:1, 1).'];
Zside = [Z(1, :) ...
         Z(2:R, C).' ...
         Z(R, (C-1):-1:1) ...
         Z((R-1):-1:1, 1).'; ...
         zeros(1, 2*(R+C)-3)];

surf(X, Y, Z);  % Plot top surface
hold on;
surf(Xside, Yside, Zside, ...  % Plot all four sides...
     'EdgeColor', 'none', ...  %   with no edge coloring (i.e. grid)...
     'FaceAlpha', 0.5);        %   and transparency
view(-120, 30);

And the resulting plot:

enter image description here

like image 146
gnovice Avatar answered Oct 01 '22 08:10

gnovice


The only way I can think is by looping over the edges, and filling them accordingly.

[X,Y] = meshgrid(1:0.5:10,1:20);

Z = X.* sqrt(Y);

figure;


p=parula; % please do not use jet :(

surf(X,Y,Z) 
hold on;

%XZ init
for ii=1:size(Z,2)-1
    patch([X(1,ii) X(1,ii+1)  X(1,ii+1) X(1,ii)],...
          [Y(1,1) Y(1,1) Y(1,1) Y(1,1)],...
          [0  0 Z(1,ii+1) Z(1,ii) ],[p(1,:)]);
end

%XZ end
for ii=1:size(Z,2)-1
    patch([X(end,ii) X(end,ii+1)  X(end,ii+1) X(end,ii)],...
          [Y(end,1) Y(end,1) Y(end,1) Y(end,1)],...
          [0  0 Z(end,ii+1) Z(end,ii) ],[p(1,:)]);
end

%YZ init
for ii=1:size(Z,1)-1
    patch([X(1,1) X(1,1) X(1,1) X(1,1)],...
          [Y(ii,1) Y(ii+1,1) Y(ii+1,1) Y(ii,1)],...
          [0  0 Z(ii+1,1) Z(ii,1) ],[p(1,:)]);
end

%YZ end
for ii=1:size(Z,1)-1
    patch([X(1,end) X(1,end) X(1,end) X(1,end)],...
          [Y(ii,end) Y(ii+1,end) Y(ii+1,end) Y(ii,end)],...
          [0  0 Z(ii+1,end) Z(ii,end) ],[p(1,:)]);
end
colorbar

xlabel('Distance between two spatial points \xi_i & \xi_j (\xi_i - \xi_j)');

ylabel('Density(\rho)');

zlabel('Transmission Delay (t_t)');

There are a lot of style choices you can make now, like removing edges or changing the colors that I will leave to you as they can be found online.

If this is not exactly what you wanted, its still pretty much the way to do it. Using patch and appropriate coordinates.

enter image description here

like image 44
Ander Biguri Avatar answered Oct 01 '22 08:10

Ander Biguri