2015-11-29 1 views
5

Desidero ggplot tracciare in un ordine specifico per controllare cosa è visibile quando gli oggetti si sovrappongono. Ogni riga di dati viene mappata su un composito di 2 livelli geometrici - i particolari della trama lo richiedono. Ho usato un ciclo per farlo, ma è molto lento. Mi chiedo se c'è un modo migliore? per esempio.Controllo dell'ordine di stampa per oggetti visivi con più geometrie in ggplot2

d = data.frame(x=c(1,5,2,2,4,2), y=c(1,1,4,3,3,5), grp=c(1,1,1,2,2,2)) 

ggplot(d, aes(x, y, group=grp)) + 
    geom_polygon(aes(fill = factor(grp))) + 
    geom_line(size=1) 

enter image description here

Ogni linea poligono deve tracciare con il poligono - così ad esempio la linea del poligono rosso dovrebbe essere oscurata dal poligono del blu. C'è un modo per ottenere ciò senza il ciclo quando sia lo geom_polygon che lo geom_line usano lo stesso set di dati?


Edit: metodi di loop ..

Qui ci sono metodi di loop che ho usato. Aggiunto un set di dati migliore per confrontare le prestazioni. Entrambi richiedono circa 5.6 secondi per funzionare sulla mia macchina. Per confronto, l'approccio tipico (ggplot(d, aes(x, y, fill=factor(grp))) + geom_polygon() + geom_line(size=1)) richiede 0,45 secondi.

d = data.frame(x = sample(-30:30,99,rep=T) + rep(sample(1:100,33),each=3), 
       y = sample(-30:30,99,rep=T) + rep(sample(1:100,33),each=3), 
       grp = rep(1:33,each=3)) 

# Method 1 - for loop 
p = ggplot() 
for(g in unique(d$grp)){ 
    dat = subset(d, grp == g) 
    p = p + geom_polygon(data=dat, aes(x, y, fill = factor(grp))) + 
    geom_line(data=dat, aes(x, y), size=1) 
} 
print(p) 

# Method 2 - apply 
ggplot() + lapply(unique(d$grp), FUN=function(g){ 
    dat = subset(d, grp == g) 
    list(geom_polygon(data=dat, aes(x, y, fill = factor(grp))), 
     geom_line(data=dat, aes(x, y), size=1)) 
}) 

enter image description here

+0

Credo che il problema che stai affrontando abbia a che fare con la linea. Se rimuovi la geom_line() ottieni il risultato desiderato. Inoltre, se metti geom_line prima di geom_polygon() ottieni quello che penso sia l'output desiderato –

+1

Puoi mostrare il ciclo for che stai usando? – Heroka

+0

@geotheory Mi dispiace, non ho soluzione. L'unica idea che ho è di creare un poligono extra per ogni gruppo che è leggermente più grande sui lati se si ha bisogno della linea, e tracciare quelli prima in nero e poi sovrapporre a colori. Tuttavia, penso che ci vorrebbe più tempo per programmare/test di quanto ci vuole per eseguire il ciclo per generare l'immagine. – Heroka

risposta

1

ho appena usato il codice e ha cambiato l'ordine dei livelli nel ggplot2 Sembra che questo

d = data.frame(x=c(1,5,2,2,4,2), y=c(1,1,4,3,3,5), grp=c(1,1,1,2,2,2)) 

ggplot(d, aes(x, y, group=grp)) + 
    geom_line(size=1)+ 
    geom_polygon(aes(fill = factor(grp))) 

e il risultato è questo uno

enter image description here

Si noti inoltre che se si rimuove la chiamata geom_line si produce lo stesso risultato ma senza il bordo.

+0

Scusa Matian che non aiuta davvero. Stai solo tracciando tutte le linee prima (quindi sotto) tutti i poligoni. Guarda come il poligono blu-verde ha perso parte della linea .. – geotheory

+0

Capisco. Per quanto riesca a pensare in questo momento, suggerirei di abbandonare la linea (non bordura comunque i triangoli nell'esempio originale). Ci penserò un secondo dopo. Sto pensando che geom_line potrebbe non essere il modo migliore per farlo ... forse geom_segment –

+0

Sì, la linea è solo un esempio dimostrativo. La mia visualizzazione richiede 2 geometrie separate. – geotheory