10

bar3 plot コマンドで生成した 2-D ヒストグラム (プロットは 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)
4

3 に答える 3

13

1 つの解決策は、 で作成されたグラフィックス オブジェクトを変更することbar3です。まず、 から返されたハンドルを取得する必要がありますbar3

h = bar3(z);

あなたの場合、h色付きのバーのセットごとに 1 つずつ、ハンドルの 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-by-1長方形のパッチ (つまり、各ビンの立方体の 6 つの面)bar3をプロットします。長方形の面ごとに 4 つのコーナーがあるため、 のパッチ オブジェクトの各セット6*Nのプロパティは になります。したがって、プロパティの 6 行の各クラスターは、1 つのビンの 6 つの面の z 座標のセットです。'ZData'h(6*N)-by-4'ZData'

上記のコードは、最初にビン カウントが 0 に等しいすべての場所で 1 を持つ論理ベクトルを作成し、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
于 2010-01-12T16:51:58.070 に答える
7

値がゼロのバーを非表示にする方法を示す例を次に示します。通常のBAR3プロットから始めます。

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

前

変数hにはハンドルの配列が含まれていることに注意してくださいsurface(この場合は 3 つ、バーの「グループ」ごとに 1 つ。グループは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と同じもの) として表されます。ここで、N は各グループ内の長方形のバーの数、または上記の例では 7 です。XDataYDataCData

このように、各長方形は 6x4 の行列 (X/Y/Z 座標ごとに 1 つ) で表されます。たとえば、そのような長方形の座標は次のようになります。

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

それぞれの 2 列目は左面に沿って点をトレースし、3 列目は右面に沿って点をトレースします。2 つを接続すると、長方形の 4 つの面が描画されます。

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

四角形の表面

最初と最後の列は、長方形の辺を閉じることによって残りの 2 つの面を描画します。

このような行列はすべて 1 つの背の高い行列として連結され、四角形はすべて 1 つのサーフェス オブジェクトを使用して描画されます。これは、NaN値を使用して、同じ四角形のポイント内と異なる四角形の間の両方で、異なる部分を分離することによって実現されます。

したがって、上記のコードが行うことは、Z 高さがゼロの四角形を探し、そのすべての値をNaNMATLAB にそれらの点によって形成される面を描画しないように効果的に指示する値で置き換えることです。

于 2013-07-04T19:52:48.313 に答える
1

私の問題はゼロ値ではなく、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

ありがとう!

于 2011-04-29T09:51:16.560 に答える