Frage

Ich habe ein 2-D-Histogramm (die Handlung ist 3D - mehrere Histogramme grafisch dargestellt wird, Seite an Seite), dass habe ich erzeugt mit bar3 plot-Befehl.Jedoch, alle die null-Werte als flache Felder in der x-y-Ebene.Gibt es eine Möglichkeit kann ich verhindern, dass MATLAB die Anzeige der Werte?Ich habe bereits versucht, den Austausch aller Nullen mit NaNs, aber es hat sich nicht geändert, nichts über die Handlung.Hier ist der code, den ich habe experimentiert mit:

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)

Wie Sie sehen können, gibt es durchaus ein paar null-Werte auf dem Grundstück.Schließen der Abbildung und dem re-Plotten nach dem Austausch Nullen mit NaNs scheint nichts zu ändern:

close
z(z==0)=NaN;
bar3(z)
War es hilfreich?

Lösung

Eine Lösung ist die Grafik ändern Objekte erstellt von bar3 . Zuerst müssen Sie die Griffe erhalten zurück von bar3 :

h = bar3(z);

In Ihrem Fall h wird ein 3-Element-Vektor von Griffen, einer für jeden Satz von farbigen Balken. Der folgende Code sollte dann macht die Behälter mit Zählungen von Null unsichtbar:

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

Und hier ist eine Darstellung (mit obligatorischer Freihand Kreisen):

Wie es funktioniert ...

Wenn Ihr Vektor sind Zählungen N-by-1, dann bar3 6*N rechteckigen Patches (dh die 6 Flächen eines Quaders für jeden Behälter) wird plotten. Die 'ZData' Eigenschaft für jede Gruppe von Patch-Objekte in h wird daher (6*N)-by-4 sein, da es 4 Ecken für jede rechteckige Fläche. Jeder Cluster von 6 Zeilen der 'ZData' Eigenschaft ist daher eine Reihe von Z-Koordinaten für die 6 Flächen eines ist.

Der obige Code zuerst eine logische Vektor mit Einsen erzeugt überall die Binärzahl gleich 0, repliziert dann jedes Element dieses Vektors 6 mal den kron Funktion. Dies wird ein Index für die Zeilen der 'ZData' Eigenschaft und dieser Index verwendet wird, um den z-Koordinaten nan für den Patches von leeren Behältern. Dadurch wird die Flecken verursachen, nicht wiedergegeben werden.


EDIT:

Hier ist eine leicht modifizierte Version des Codes, der durch Abrufen der Stangenhöhe von der 'ZData' Eigenschaft der aufgetragenen Bars, so alles, was für sie zu arbeiten sind die Griffe wieder von bar3 . Ich habe auch den Code in einer Funktion (ohne Fehler und Eingangsprüfung) gewickelt:

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

Andere Tipps

Hier ist ein Beispiel, das zeigt, wie der hide-bars mit null-Werten.Wir starten mit einem normalen BAR3 plot:

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

before

Beachten Sie, dass die variable h enthält ein array von surface Griffe (3 in diesem Fall, eine für jede "Gruppe" von bars.Die Gruppen entsprechen den Spalten der Y matrix, jedes in einer anderen Farbe dargestellt).

Und jetzt ist der code zum ausblenden von null-Werten:

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

Erklärung:

Für jede Gruppe von Balken, eines surface Grafik-Objekt wird erstellt (mit Griff gespeichert h(i)).Es ist Z-Koordinaten der matrix ZData wird dargestellt als eine 6*N-by-4 matrix (gleiche Sache für XData, YData, und CData Matrizen), wobei N die Anzahl der rechteckigen Balken in jeder Gruppe oder 7 in dem obigen Beispiel.

Jedes Rechteck ist vertreten mit 6x4-Matrizen (eine für jede X/Y/Z-Koordinaten).Zum Beispiel die Koordinaten eines solchen Rechtecks würde wie folgt Aussehen:

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

Die zweite Spalte der einzelnen Spuren die Punkte entlang der linken Seite, die Dritte Spalte die Spuren der Punkte entlang der rechten Gesicht, und wenn die beiden verbunden sind, würde die 4 Gesichter zeichnen des Rechtecks:

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

Die ersten und letzten Spalten ziehen würde, die beiden verbleibenden Flächen durch die Schließung der Seiten des Rechtecks.

Alle diese Matrizen sind verkettet, als ein hoch-matrix, und die Rechtecke sind alle gezeichnet, mit einer einzigen Oberfläche Objekt.Dies wird erreicht durch die Verwendung NaN Werte zu trennen, die aus verschiedenen teilen, sowohl innerhalb der Punkte der gleichen Rechteck, und in-zwischen ist der Unterschied Rechtecke.

Also, was der obige code tut, ist zu suchen, Rechtecke, wo die Z-Höhe gleich null ist, und ersetzen Sie alle Ihre Werte mit NaN Werte, die effektiv erzählt MATLAB nicht zu ziehen die Oberflächen gebildet durch die Punkte.

Mein Problem war nicht Null-Werte, aber NaN-Werte (die in Null-Werte innerhalb von bar3 umgewandelt werden). Ich wollte Element mit Werten halten Null anzeigt, nicht aber die Elemente mit dem Wert nan. Ich stellte den Code leicht, und es funktionierte perfekt:

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

Danke!

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top