【问题标题】:How do I mark (or) shade the area below the graph of Surface plot in Matlab?如何在 Matlab 中标记(或)遮蔽曲面图下方的区域?
【发布时间】:2019-05-29 11:01:44
【问题描述】:

我正在尝试为以下等式绘制 3D 曲面图 t_t

[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)');

【问题讨论】:

  • 你能展示一个你想要的示例图片吗?类似surfc?
  • @AnderBiguri 嗨。谢谢回复。但我不是在寻找 surfc 命令。我正在寻找类似 @​​987654322@ 的东西。但我使用 3D 绘画进行了编辑。是否有任何matlab命令可以标记这条曲线下的区域?

标签: matlab


【解决方案1】:

您可以通过构建一组新矩阵来添加额外的表面以传递给surf,并根据您希望结果的外观提供一些不同的选项...

选项#1:填充侧面,一个表面对象:

如果您只想填写边,您可以在矩阵的每一边添加一个新的行和列,如下所示:

[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);

这允许您通过一次调用surf 来绘制曲面和侧面,结果如下:


选项#2:填充侧面和底部,一个表面对象:

如果您还想填充形状的底部,您可以通过添加新列将表面包裹在其自身周围和下方,然后在顶部和底部添加新行以封闭末端:

[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);

同样,您只需调用surf 即可绘制整个封闭曲面。这是底部的视图,显示了封闭的底部:


选项#3:为侧面添加一个单独的表面对象:

将所有内容绘制为一个对象时,如果您想以不同于顶部的方式渲染侧面,则会受到限制。使侧面像Ander does 那样分隔对象(使用patch 或单独调用surf)将使您能够更好地控制它们相对于顶面的着色方式。要为所有四个边创建一个曲面对象,您可以提取矩阵边缘周围的条目并根据需要复制它们:

[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);

以及由此产生的情节:

【讨论】:

  • 比我的更容易:D 我做了另一个,因为我不清楚这是否正是 OP 想要的,但如果是,这就是方式
  • 感谢您的大力帮助。这是我正在寻找的壁橱。 @AnderBiguri 抱歉描述不清楚。
  • @hkshks:乐于助人!只是检查...您的意思是将我的答案或 Hoki 的答案标记为已接受?
  • @gnovice 对不起,我的错。我是这个社区的新手。我已将您的答案标记为已接受。无论如何,我无法理解这部分代码。 Xside = [1; 1]*[X(1, :) X(2:R, C)。 ... X(R, (C-1):-1:1) X((R-1):-1:1, 1).']; 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).'; ... 零(1, 2*(R+C)-3)];
  • @hkshks:我在该部分添加了几个 cmets 以使其更清晰一些。基本上,您只是围绕矩阵的周边进行跟踪并收集边缘值。 [1; 1]*[...]部分只是使用矩阵乘法来复制边缘值的行向量,相当于repmat([...], 2, 1)
【解决方案2】:

我能想到的唯一方法是在边缘上循环,并相应地填充它们。

[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)');

您现在可以选择很多样式,例如去除边缘或更改颜色,我将留给您,因为它们可以在网上找到。

如果这不是您想要的,它仍然是实现它的方法。使用patch 和适当的坐标。

【讨论】:

  • 非常感谢您的帮助。
【解决方案3】:

这是使用patch 对象的另一种方式。

此解决方案与 Ander 的解决方案非常相似,但 patch 构造的处理方式不同,因此您无需循环并最终只处理 4 个补丁实体。

%% Prepare domain limits
xLim = [1 10] ; xStep = 0.5 ;
yLim = [1 20] ; yStep = 1 ;

x = xLim(1):xStep:xLim(2) ;
y = yLim(1):yStep:yLim(2) ;

%% Your code
[X,Y] = meshgrid(x,y);
Z = X.* sqrt(Y);
figure;
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)');

%% prepare patch elements
zLim = [min(Z) max(Z)] ;
pcol = [0.2857,1,0.7143] ;

xface = [ x xLim(2) xLim(1) ] ;
yface = [ y yLim(2) yLim(1) ] ;
xface0 = zeros(size(xface)) ;
yface0 = zeros(size(yface)) ;
xfaceZ = [zeros(size(x)) zLim(1) zLim(1)] ;
yfaceZ = [zeros(size(y)) zLim(1) zLim(1)] ;

%% display the patches
hp(1) = patch( xface , xface0+yLim(1) , xfaceZ ,pcol ) ;
hp(3) = patch( xface , xface0+yLim(2) , xfaceZ ,pcol ) ;
hp(2) = patch( yface0+xLim(1) , yface , yfaceZ ,pcol ) ;
hp(4) = patch( yface0+xLim(2) , yface , yfaceZ ,pcol ) ;

%% update top edge of patches
% to connect to the surface edges
hp(1).ZData(1:end-2) = Z(1,:) ;
hp(2).ZData(1:end-2) = Z(:,1) ;
hp(3).ZData(1:end-2) = Z(end,:) ;
hp(4).ZData(1:end-2) = Z(:,end) ;

%% Color according to preferences
set(hp, 'Facecolor',pcol , 'FaceAlpha',0.5 , 'EdgeColor','none')

将呈现:

【讨论】:

  • 感谢您的大力帮助。
猜你喜欢
  • 1970-01-01
  • 2015-12-19
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-30
相关资源
最近更新 更多