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

如何在MATLAB中隐藏bar3绘图中的零值,matlab,plot,data-visualization,histogram,Matlab,Plot,Data Visualization,Histogram,我有一个2-D柱状图(图是3D的,几个柱状图并排绘制),这是我用bar3 plot命令生成的。但是,所有零值在x-y平面中显示为平面正方形。有没有办法阻止MATLAB显示这些值?我已经尝试过用NaNs替换所有的零,但是它没有改变任何关于情节的东西。以下是我一直在尝试的代码: x1=normrnd(50,15,100,1); %generate random data to test code x2=normrnd(40,13,100,1); x3=normrnd(65,12,100,1); l

我有一个2-D柱状图(图是3D的,几个柱状图并排绘制),这是我用bar3 plot命令生成的。但是,所有零值在x-y平面中显示为平面正方形。有没有办法阻止MATLAB显示这些值?我已经尝试过用NaNs替换所有的零,但是它没有改变任何关于情节的东西。以下是我一直在尝试的代码:

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)

一种解决方案是修改由创建的图形对象。首先,您必须从以下位置获取返回的句柄:

在您的例子中,
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
下面是一个示例(必须使用自由手圆圈):

它是如何工作的。。。 如果箱子计数的向量为
N×1
,则将绘制
6*N
矩形面片(即每个箱子的长方体的6个面)。因此,
h
中每组面片对象的
'ZData'
属性将是
(6*N)-by-4
,因为每个矩形面有4个角。因此,
'ZData'
属性的每个6行簇是一个箱子的6个面的一组z坐标

上面的代码首先创建一个逻辑向量,其中bin count等于0的地方都是1,然后使用函数将该向量的每个元素复制6次。这将成为
'ZData'
属性行的索引,该索引用于为空存储箱的补丁设置z坐标。这将导致不渲染面片


编辑:

这里有一个稍微修改过的代码版本,它通过从绘制的条的顶部获取条的高度使代码更加通用,因此它工作所需的只是从中返回的句柄。我还将代码包装在一个函数中(sans错误和输入检查):


我的问题不是零值,而是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

谢谢

下面是一个示例,演示如何隐藏具有零值的条。我们从一个标准图开始:

请注意,变量
h
包含一个句柄数组(在本例中为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

说明: 对于每组条形图,将创建一个
曲面
图形对象(句柄存储在
h(i)
)。它的Z坐标矩阵
ZData
表示为
6*N×4
矩阵(与
XData
YData
CData
矩阵相同),其中N是每组中的矩形条数,或是上述示例中的7

这样,每个矩形用6x4矩阵表示(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)

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

所有这些矩阵都连接为一个高矩阵,并且所有矩形都使用单个曲面对象绘制。这是通过使用
NaN
值来分离不同的部分来实现的,这两个部分都位于同一矩形的点内,也位于不同的矩形之间


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

我在问了这个问题后,有了修改对象属性的想法,但我不知道从哪里开始。您的代码工作得很好-我将它放在一个m文件bar3nonzero中,现在我有了一个轻松的方法来生成绘图。@gnovice:+1..您又一次找到了kron函数的一个很好的用途:)如果我可以建议的话,我将替换line index=logical(kron(z(:,I)==0,one(6,1));索引=逻辑(克朗(abs(z(:,i))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
>> 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
>> surface(xx(1:6,2:3), yy(1:6,2:3), zz(1:6,2:3), cc(1:6,2:3))
>> view(3)