繁体   English   中英

如何在MATLAB中的bar3图中隐藏零值

[英]How to hide zero values in bar3 plot in MATLAB

我用bar3 plot命令生成了二维直方图(绘图是3D - 几个直方图并排绘制的直方图)。 但是,所有零值在xy平面中显示为平面正方形。 有没有办法阻止MATLAB显示值? 我已经尝试用NaN替换所有零,但它没有改变关于该情节的任何内容。 这是我一直在试验的代码:

x1=normrnd(50,15,100,1); %generate random data to test code
x2=normrnd(40,13,100,1);
x3=normrnd(65,12,100,1);

low=min([x1;x2;x3]);
high=max([x1;x2;x3]);
y=linspace(low,high,(high-low)/4); %establish consistent bins for histogram
z1=hist(x1,y);
z2=hist(x2,y);
z3=hist(x3,y);
z=[z1;z2;z3]';
bar3(z)

如您所见,图中有相当多的零值。 用NaN替换零后关闭数字并重新绘图似乎没有任何改变:

close
z(z==0)=NaN;
bar3(z)

一种解决方案是修改bar3创建的图形对象。 首先,你必须从bar3返回bar3

h = bar3(z);

在你的情况下, h将是一个3元素的句柄向量,每组彩色条一个。 然后,以下代码应使计数为零的二进制文件不可见:

for i = 1:numel(h)
  index = logical(kron(z(:, i) == 0, ones(6, 1)));
  zData = get(h(i), 'ZData');
  zData(index, :) = nan;
  set(h(i), 'ZData', zData);
end

这是一个例子(有强制性的自由圈):

在此输入图像描述

这个怎么运作...

如果您的bin计数向量是N-by-1 ,那么bar3将绘制6*N矩形块(即每个bin的长方体的6个面)。 因此, h每组补丁对象的'ZData'属性将是(6*N)-by-4 ,因为每个矩形面有4个角。 因此, 'ZData'属性的6行的每个簇是一个bin的6个面的一组z坐标。

上面的代码首先创建一个逻辑向量,其中bin计数等于0,然后使用kron函数复制该向量的每个元素6次。 这将成为'ZData'属性行的索引,此索引用于将空坐标的补丁的z坐标设置为nan 这将导致修补程序无法呈现。


编辑:

这是一个稍微修改过的代码版本,通过从绘制条形图的'ZData'属性中获取条形高度使其更加通用,因此它所需要的只是从bar3返回的句柄。 我还将代码包装在一个函数中(没有错误和输入检查):

function remove_empty_bars(hBars)
  for iSeries = 1:numel(hBars)
    zData = get(hBars(iSeries), 'ZData');  % Get the z data
    index = logical(kron(zData(2:6:end, 2) == 0, ones(6, 1)));  % Find empty bars
    zData(index, :) = nan;                 % Set the z data for empty bars to nan
    set(hBars(iSeries), 'ZData', zData);   % Update the graphics objects
  end
end

这是一个示例,显示如何隐藏具有零值的条形图。 我们从正常的BAR3情节开始:

x = 1:7;
Y = jet(numel(x));
h = bar3(x,Y,'detached');
xlabel x; ylabel y; zlabel z; box on;

之前

请注意,变量h包含一个surface处理数组(在这种情况下为3,每个“组”条形一个。这些组对应于Y矩阵的列,每个列用不同的颜色表示)。

现在隐藏零值的代码:

for i=1:numel(h)
    %# get the ZData matrix of the current group
    Z = get(h(i), 'ZData');

    %# row-indices of Z matrix. Columns correspond to each rectangular bar
    rowsInd = reshape(1:size(Z,1), 6,[]);

    %# find bars with zero height
    barsIdx = all([Z(2:6:end,2:3) Z(3:6:end,2:3)]==0, 2);

    %# replace their values with NaN for those bars
    Z(rowsInd(:,barsIdx),:) = NaN;

    %# update the ZData
    set(h(i), 'ZData',Z)
end

后

说明:

对于每组条形,创建surface图形对象(句柄存储在h(i) )。 它的z坐标矩阵ZData被表示为6*N-by-4矩阵(对于同样的事XDataYDataCData矩阵),其中N是在上面的示例中,每个基团或7中的矩形条的数量。

这样,每个矩形用6×4矩阵表示(每个矩阵对应一个X / Y / Z坐标)。 例如,一个这样的矩形的坐标看起来像:

>> xx = get(h(3),'XData'); yy = get(h(3),'YData'); zz = get(h(3),'ZData');

>> xx(1:6,:)
ans =
          NaN          2.6          3.4          NaN
          2.6          2.6          3.4          3.4
          2.6          2.6          3.4          3.4
          NaN          2.6          3.4          NaN
          NaN          2.6          3.4          NaN
          NaN          NaN          NaN          NaN

>> yy(1:6,:)
ans =
          NaN          0.6          0.6          NaN
          0.6          0.6          0.6          0.6
          1.4          1.4          1.4          1.4
          NaN          1.4          1.4          NaN
          NaN          0.6          0.6          NaN
          NaN          NaN          NaN          NaN

>> zz(1:6,:)
ans =
          NaN            0            0          NaN
            0            1            1            0
            0            1            1            0
          NaN            0            0          NaN
          NaN            0            0          NaN
          NaN          NaN          NaN          NaN

每个第二列跟踪左侧的点,第三列跟踪右侧的点,当两者连接时将绘制矩形的4个面:

>> surface(xx(1:6,2:3), yy(1:6,2:3), zz(1:6,2:3), cc(1:6,2:3))
>> view(3)

rectangle_surface

第一列和最后一列将通过关闭矩形的边来绘制剩余的两个面。

所有这些矩阵都连接成一个高矩阵,矩形全部使用单个表面对象绘制。 这是通过使用NaN值来分隔同一矩形的点内部和差异矩形之间的不同部分来实现的。

因此,上面的代码所做的是查找Z高度为零的矩形,并用NaN值替换其所有值,这有效地告诉MATLAB不要绘制由这些点形成的表面。

我的问题不是零值,而是NaN值(在bar3中转换为零值)。 我想继续显示值为零的元素,但不显示值为nan的元素。 我稍微调整了代码,它完美地工作:

for i = 1:numel(h)
  index = logical(kron(isnan(z(:,i)),ones(6,1)));
  zData = get(h(i),'ZData');
  zData(index,:) = nan;
  set(h(i),'ZData',zData);
end

谢谢!

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM