Как скрыть нулевые значения на графике bar3 в MATLAB - PullRequest
10 голосов
/ 12 января 2010

У меня есть двумерная гистограмма (график 3D - несколько гистограмм, нанесенных рядом друг с другом), которые я сгенерировал с помощью команды bar3 plot.Тем не менее, все нулевые значения отображаются в виде плоских квадратов в плоскости ху.Есть ли способ предотвратить отображение значений в 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)

Ответы [ 3 ]

13 голосов
/ 12 января 2010

Одним из решений является изменение графических объектов, созданных с помощью 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

А вот иллюстрация (с обязательными кружками от руки):

enter image description here

Как это работает ...

Если ваш вектор количества бинов равен N-by-1, то bar3 будет отображать 6*N прямоугольных пятен (то есть 6 граней кубоида для каждого бина). Поэтому свойство 'ZData' для каждого набора объектов исправлений в h будет равно (6*N)-by-4, поскольку для каждой прямоугольной грани имеется 4 угла. Поэтому каждый кластер из 6 строк свойства 'ZData' представляет собой набор z-координат для 6 граней одного элемента.

Приведенный выше код сначала создает логический вектор с единицами везде, где количество бинов равно 0, а затем 6 раз реплицирует каждый элемент этого вектора с помощью функции kron. Это становится индексом для строк свойства 'ZData', и этот индекс используется для установки z-координат на nan для исправлений пустых корзин. Это приведет к тому, что патчи не будут обработаны.


EDIT:

Вот немного измененная версия кода, которая делает его более общим, выбирая высоту столбца из свойства '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
7 голосов
/ 04 июля 2013

Вот пример, который показывает, как скрыть бары с нулевыми значениями. Мы начинаем с нормального BAR3 сюжета:

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

before

Обратите внимание, что переменная 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

after

Пояснение:

Для каждой группы столбцов создается графический объект surface (дескриптор хранится в h(i)). Это матрица Z-координат ZData, представленная в виде матрицы 6*N-by-4 (то же самое для матриц XData, YData и CData), где 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 не рисовать поверхности, образованные этими точками.

1 голос
/ 29 апреля 2011

Моя проблема была не в нулевых значениях, а в значениях 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

Спасибо!

...