MATLAB:在表面图上绘图

时间:2016-10-15 08:16:37

标签: matlab plot surface

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

surf(X, Y, data);
colormap(jet);
colobar;
view(2);

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

的东西
  

enter image description here

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

  

enter image description here

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

  

enter image description here

然而,我似乎无法实现这一点,因为在绘图上绘制平面内元素使它们出现在x-y轴上,这被我的表面图覆盖。例如,调用

circle_pos = [ +1 +1; -1 -1; -1 +1; +1 -1;]
circle_rad = 0.2 * ones(4,1);
viscircles(circle_pos, circle_rad);

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

  

enter image description here

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

2 个答案:

答案 0 :(得分:6)

可能没有直接方式来指定z返回的对象的viscircles位置,但一般情况下(大部分时间)都有一种方式之后修改任何图形对象的属性和位置。

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

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

hg = viscircles(circle_pos, circle_rad);

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

转换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

完成后,您的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

您现在可以调用此函数而不是viscircles。我使用varargin参数将所有line属性转移到创建的圈子中(因此您可以指定ColorLineWidth以及您喜欢的任何其他典型参数。

为了举个例子,我需要重新创建一个与你的表面相当的表面,在最大值周围分布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

哪个产生: 3d surf

现在,您只需使用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) ;

并得到: enter image description here

请注意,我创建了此功能,因此它还会返回包含您的线条(圆圈)的hggroup对象。因此,如果您希望稍后移动,请应用与答案的第一部分相同的技巧。

答案 1 :(得分:2)

我想到了几个选择。

最简单的方法是使用plot3

在3d中绘制标记
figure;
peaks;
shading interp;
hold;
x = 0; y = 2; z = 10;
plot3(x, y, z, 'ro', 'MarkerSize', 24);

这样可行,但圆圈似乎总是面向观众: plot3 marker plot3 marker in 3d

或者,您可以在3d中绘制圆圈:

vfTheta = linspace(0, 2*pi, 300);
figure; peaks; shading interp; hold;
x = 0; y = 2; z = 10; r = 0.2;
plot3(x + r.*cos(vfTheta), y + r.*sin(vfTheta), z .* ones(size(vfTheta)), 'r-', 'LineWidth', 2);

结果:3d中的一个漂亮的光环!

plotting a circle in 3d a nice halo