MATLAB:在表面图上绘图

Ant*_*rth 5 matlab plot surface

我正在MATLAB中绘制一个R ^ 2到R函数作为曲面图,我从上面进行颜色映射和查看.

surf(X, Y, data);
colormap(jet);
colobar;
view(2);
Run Code Online (Sandbox Code Playgroud)

它产生(带有一些额外的代码)类似的东西

在此输入图像描述

虽然函数的真实性质(为了理解这个问题)可以从以下角度更好地观察:

在此输入图像描述

我想在我的原始情节(从上面看)上绘制一个圆圈.就像是...

在此输入图像描述

然而,我似乎无法实现这一点,因为在绘图上绘制平面内元素使它们出现在xy轴上,我的表面图覆盖了它.例如,打电话

circle_pos = [ +1 +1; -1 -1; -1 +1; +1 -1;]
circle_rad = 0.2 * ones(4,1);
viscircles(circle_pos, circle_rad);
Run Code Online (Sandbox Code Playgroud)

从我的表面绘图后,从顶部查看时没有可见的圆圈.缩放和旋转显示这些圆圈在xy平面上绘制,因此从上方看不见.

在此输入图像描述

如何将我的圆圈绘制在曲面图的顶部,以便从上方可以看到它们?当text在表面上绘图时会出现类似的问题,但是通过在基础函数z值之上指定az位置值来补救.似乎没有任何方法可以指定这些图形元素的z位置.

Hok*_*oki 6

可能没有直接的方法来指定z返回的对象的位置viscircles,但通常(大多数情况下)有一种方法可以在之后修改任何图形对象的属性和位置.


方法1:创建后修改圆圈.

如果您打算对图形对象进行修改,首先要做的就是检索它handle.因此,在您的情况下,您必须viscircles通过指定返回值(将包含handle您想要的)来调用:

hg = viscircles(circle_pos, circle_rad);
Run Code Online (Sandbox Code Playgroud)

我没有,Image Processing Toolbox所以我没有访问该viscircles功能.但是我从文档中读到返回的句柄是一个hggroup.An hggroup只是一个包含一个或handles多个原始图形对象的容器.在这种情况下,hggroup包含4个句柄lines(您的4个圆圈).

转换a中所有对象的最简单方法hggroup是使用hgtransform对象.我们将定义一个翻译转换,hgtransform并将它应用于4个圆圈(所有的孩子hggroup).

要定义翻译,我们将使用一个makehgtform对象.

开始了:

ht = hgtransform ;      % create the transform object
set(hg,'Parent',ht) ;   % make it a "parent" of the hggroup

zc = max(max(Z)) ;  % Find by how much we want to translate the circles on the Z axis
Tz = makehgtform('translate',[0 0 zc]) ;   % create the TRANSLATION transform

set(ht,'Matrix',Tz)     % apply the transformation (translation) to the hggroup/hgtransform
Run Code Online (Sandbox Code Playgroud)

完成后,您的4个圆圈现在应位于表面之上.请注意,您可以为zc(不仅是曲面的最大值)指定任何其他值.


方法2:DIY

如果您不想依赖于图像处理工具箱,或者根本没有图像处理工具箱,则可以相对轻松地在3D空间中创建圆圈.

这是一个以viscircles与之相当的方式创建圆的功能,但它也允许您z为圆心位置指定可选坐标.

代码circles_3D.m:

function hg = circles_3d( pos , rad , varargin )

% get current axes handle and hold state
ax = gca ;
holdState = get(ax,'NextPlot') ;    % save state to reinstate after function
set(ax,'NextPlot','add') ;          % equivalent of "hold off"

tt = linspace(0,2*pi) ;
hg = hggroup(ax) ;
for k = 1:numel(rad)

    c = pos(k,:) ;
    r = rad(k) ;
    x = c(1) + r.*cos(tt) ;
    y = c(2) + r.*sin(tt) ;
    z = zeros(size(x)) ;
    if numel(c)==3 ; z = z + c(3) ; end

    plot3(hg,x,y,z,varargin{:}) ;
end

set(ax,'NextPlot',holdState) ; % restore axes hold state
Run Code Online (Sandbox Code Playgroud)

您现在可以调用此函数而不是viscircles.我使用的varargin参数转移任何line财产建立的社交圈(这样你就可以指定Color,LineWidth和任何其他典型的参数,你喜欢.

为了举个例子,我需要重建一个与你的表面相当的表面,在最大值周围分布4x"零"极点:

pc = 0.5 ;  % pole centers
pw = 0.05 ; % pole widths

% surface definition
[X,Y] = meshgrid(-5:.1:5);
R = sqrt(X.^2 + Y.^2) + eps ;
Z = sin(R)./R;
% zero surface values around the defined poles
[idxPoles] = find(abs(X)>=pc-pw & abs(X)<=pc+pw & abs(Y)>=pc-pw & abs(Y)<=pc+pw ) ;
Z(idxPoles)= 0 ;
% display
hs = surf(X,Y,Z) ; shading interp
Run Code Online (Sandbox Code Playgroud)

哪个产生: 3d冲浪

现在,您只需使用该circles_3D功能获取您的圈子:

zc = max(max(Z)) ;
circle_pos = [ pc pc zc ; -pc -pc zc ; -pc +pc zc ; +pc -pc zc ] ;
circle_rad = 0.2 * ones(4,1);
h = circles_3d( circle_pos , circle_rad , 'Color','r','LineWidth',2) ;
Run Code Online (Sandbox Code Playgroud)

得到: 在此输入图像描述


请注意,我创建了这个函数,因此它还返回一个hggroup包含行(圆圈)的对象.因此,如果您想稍后移动它们,请应用与答案的第一部分相同的技巧.