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