Domanda

Ho un istogramma 2-D (la trama è 3D - vari istogrammi affiancati graficamente) che ho generato con il comando plot Bar3. Tuttavia, tutti i valori zero appaiono come quadrati piane nel piano x-y. C'è un modo per evitare che MATLAB dalla visualizzazione dei valori? Ho già provato a sostituire tutti gli zeri con NaNs, ma non ha cambiato nulla sulla trama. Ecco il codice che ho avuto modo di sperimentare con:

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)

Come si può vedere, ci sono un bel paio di valori zero sul terreno. Chiusura della figura e ri-tracciato dopo la sostituzione zeri con NaNs sembra cambiare nulla:

close
z(z==0)=NaN;
bar3(z)
È stato utile?

Soluzione

Una soluzione è quella di modificare gli oggetti grafici creati da bar3 . In primo luogo, è necessario ottenere le maniglie tornato da bar3 :

h = bar3(z);

Nel tuo caso, h sarà un 3-vettore elemento di maniglie, una per ogni serie di barre colorate. Il seguente codice dovrebbe poi fare i cassonetti con i conteggi di nulla invisibile:

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

Ed ecco un esempio (con obbligatorie cerchi a mano libera):

entrare descrizione dell'immagine qui

Come funziona ...

Se il vettore di bin conta è N-by-1, quindi bar3 traccierà patch rettangolari 6*N (cioè le 6 facce di un parallelepipedo per ciascun bin). La proprietà 'ZData' per ogni insieme di oggetti di patch in h sarà quindi (6*N)-by-4, poiché ci sono 4 angoli per ogni faccia rettangolare. Ogni gruppo di 6 file dell'immobile 'ZData' è quindi un insieme di coordinate z per 6 facce di un raccoglitore.

Il codice di cui sopra prima crea un vettore logica con quelli ovunque il conteggio bidone è uguale a 0, poi replica ogni elemento di questo vettore 6 volte usando il funzione kron . Questo diventa un indice per le righe della proprietà 'ZData', e questo indice viene utilizzato per impostare le coordinate z nan per le macchie di bin vuoti. Questo farà sì che le patch di non essere resi.


Modifica

Ecco una versione leggermente modificata del codice che lo rende più generale dal recupero l'altezza della barra dal proprietà 'ZData' dei bar tracciati, in modo tutto ciò che serve per farlo funzionare sono le maniglie tornato da bar3 . Ho anche avvolto il codice in una funzione (errore di sans e l'ingresso controllo):

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

Altri suggerimenti

Ecco un esempio che mostra come nascondere barre con zero-valori. Si comincia con un normale trama Bar3 :

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

prima

Si noti che la h variabile contiene una serie di surface maniglie ( 3 in questo caso, uno per ogni "gruppo" di barre. i gruppi corrispondono alle colonne della matrice Y, ciascuna rappresentata da un colore diverso).

E ora il codice per nascondere i valori zero:

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

dopo

Spiegazione:

Per ciascun gruppo di barre, viene creato un oggetto grafico surface (con maniglia memorizzato in h(i)). È Z-coordinate matrice ZData è rappresentato come una matrice 6*N-by-4 (stessa cosa per XData, YData, e matrici CData), dove N è il numero di barre rettangolari in ciascun gruppo o 7 nell'esempio precedente.

In questo modo ogni rettangolo è rappresentato con matrici 6x4 (uno per ciascuna delle coordinate X / Y / Z). Per esempio le coordinate di un tale rettangolo sarà simile:

>> 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 seconda colonna di ciascuna traccia i punti lungo la sagoma sinistra, terza colonna traccia i punti lungo la faccia giusta, e quando i due sono collegati richiama 4 facce del rettangolo:

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

Il primo e l'ultimo colonne richiama l'due facce rimanenti chiudendo i lati del rettangolo.

Tutte tali matrici sono concatenati come una matrice alto, ed i rettangoli sono attratti utilizzando un unico oggetto di superficie. Ciò si ottiene utilizzando i valori NaN per separare le varie parti, sia all'interno dei punti dello stesso rettangolo, e in-tra i rettangoli differenza.

Quindi, quello che il codice di cui sopra non è quello di cercare rettangoli dove la Z-altezza è pari a zero, e sostituire tutti i suoi valori con i valori NaN che racconta in modo efficace MATLAB non trarre le superfici formate da quei punti.

Il mio problema non è stato valori zero, ma i valori NaN (che vengono convertiti in valori zero all'interno di Bar3). Ho voluto mantenere la visualizzazione di elementi con valori pari a zero, ma non gli elementi con valore di nan. Ho regolato il codice un po ', e ha funzionato perfettamente:

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

Grazie!

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top