Question

I ai un histogramme 2-D (l'intrigue est 3D - plusieurs histogrammes représentés graphiquement côte à côte) que je suis généré avec la commande de tracé de bar3. Cependant, toutes les valeurs nulles apparaissent comme des carrés plats dans le plan x-y. Est-il possible que je peux empêcher Matlab d'afficher les valeurs? Je l'ai déjà essayé de remplacer tous les zéros avec NaN, mais cela n'a rien changé sur le terrain. Voici le code que je l'ai expérimenté avec:

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)

Comme vous pouvez le voir, il y a un bon nombre de valeurs nulles sur le terrain. Fermeture de la figure et re-traçage après avoir remplacé les zéros avec NaN semble rien changer:

close
z(z==0)=NaN;
bar3(z)
Était-ce utile?

La solution

Une solution consiste à modifier les objets graphiques créés par bar3 . Tout d'abord, vous devez obtenir les poignées de retour bar3 :

h = bar3(z);

Dans votre cas, h sera un vecteur 3 éléments de poignées, un pour chaque ensemble de barres de couleur. Le code suivant doit alors faire les bacs avec un nombre de zéro 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

Et voici une illustration (avec des cercles sans main obligatoire):

Comment ça marche ...

Si votre vecteur de bin compte est N-by-1, puis bar3 machineront patches 6*N rectangulaires (à savoir les 6 faces d'un parallélépipède pour chaque bin). La propriété 'ZData' pour chaque ensemble d'objets de brassage dans h sera donc (6*N)-by-4, puisqu'il y a 4 coins de chaque face rectangulaire. Chaque groupe de 6 rangées de la propriété 'ZData' est donc un ensemble de coordonnées z pour les 6 faces d'une poubelle.

Le code ci-dessus crée d'abord un vecteur logique avec les partout le nombre bin est égal à 0, puis reproduit chaque élément de ce vecteur 6 fois en utilisant le kron fonction . Cela devient un index pour les rangées de la propriété 'ZData', et cet indice est utilisé pour définir les coordonnées z nan pour les patches de bacs vides. Cela entraînera les correctifs à ne pas être rendus.


EDIT:

Voici une version légèrement modifiée du code qui le rend plus général en allant chercher la hauteur de la barre de la propriété 'ZData' des barres tracées, de sorte que tout ce qui est nécessaire pour que cela fonctionne sont les poignées de retour bar3 . J'ai aussi enveloppé le code dans une fonction (erreur de sans et entrée vérification):

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

Autres conseils

Voici un exemple qui montre comment masquer les barres avec zéro valeurs. Nous commençons par un href="http://www.mathworks.com/help/matlab/ref/bar3.html" normal complot de BAR3:

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

avant

Notez que la h variable contient une rangée de poignées surface ( 3 dans ce cas, une pour chaque « groupe » de bars. les groupes correspondent aux colonnes de la matrice de Y, chacune représentée par une couleur différente).

Et maintenant, le code pour cacher les valeurs zéro:

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

après

Explication:

Pour chaque groupe de barres, un objet graphique surface est créé (avec poignée stockée dans h(i)). Il est Z-coordonnées matrice ZData est représenté comme une matrice de 6*N-by-4 (même chose pour XData, YData, et des matrices de CData), où N est le nombre de barres rectangulaires dans chaque groupe ou 7, dans l'exemple ci-dessus.

Ainsi, chaque rectangle est représenté avec des matrices de 6x4 (une pour chacune des coordonnées X / Y / Z). Par exemple, les coordonnées d'un tel rectangle ressemblerait à ceci:

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

La deuxième colonne de chaque trace les points le long de la face gauche, la troisième colonne trace les points le long de la face droite, et lorsque les deux sont reliés attire 4 faces du rectangle:

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

Les première et dernière colonnes se rapprocher les deux faces restantes en fermant les côtés du rectangle.

Tous ces matrices sont concaténés comme une matrice de haut, et les rectangles sont tous établis à l'aide d'un seul objet de surface. Ceci est réalisé en utilisant des valeurs de NaN pour séparer les différentes parties, à la fois à l'intérieur des points de la même rectangle, et entre les rectangles de différence.

Alors que le code ci-dessus fait est de rechercher des rectangles où la hauteur Z est égal à zéro, et remplacer toutes ses valeurs avec des valeurs de NaN qui raconte efficacement MATLAB® de ne pas tirer les surfaces formées par ces points.

Mon problème était pas des valeurs zéro, mais les valeurs NaN (qui sont converties en valeurs nulles à l'intérieur de bar3). Je voulais garder l'affichage des éléments avec des valeurs zéro, mais pas les éléments à valeur nan. J'ai ajusté légèrement le code, et cela a fonctionné parfaitement:

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

Merci!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top