One solution is to modify the graphics objects created by bar3
. First, you have to get the handles returned from bar3
:
h = bar3(z);
In your case, h
will be a 3-element vector of handles, one for each set of colored bars. The following code should then make the bins with counts of zero invisible:
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
And here's an illustration (with obligatory free-hand circles):
How it works...
If your vector of bin counts is N-by-1
, then bar3
will plot 6*N
rectangular patches (i.e. the 6 faces of a cuboid for each bin). The 'ZData'
property for each set of patch objects in h
will therefore be (6*N)-by-4
, since there are 4 corners for each rectangular face. Each cluster of 6 rows of the 'ZData'
property is therefore a set of z-coordinates for the 6 faces of one bin.
The above code first creates a logical vector with ones everywhere the bin count equals 0, then replicates each element of this vector 6 times using the kron
function. This becomes an index for the rows of the 'ZData'
property, and this index is used to set the z-coordinates to nan
for the patches of empty bins. This will cause the patches to not be rendered.
EDIT:
Here's a slightly modified version of the code that makes it more general by fetching the bar height from the 'ZData'
property of the plotted bars, so all that's needed for it to work are the handles returned from bar3
. I've also wrapped the code in a function (sans error and input checking):
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
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…