2014-07-19 16 views
5

Sto cercando di creare grafici a densità multipla, per creare una "mappa di calore animata".Specifica la scala per la densità in ggplot2 stat_density2d

Dato che ogni fotogramma dell'animazione dovrebbe essere comparabile, mi piacerebbe che la densità -> la mappatura del colore su ciascun grafico sia uguale per tutti, anche se l'intervallo dei dati cambia per ognuno.

Ecco il codice che userei per ogni singolo grafico:

ggplot(data= this_df, aes(x=X, y=Y)) + 
    geom_point(aes(color= as.factor(condition)), alpha= .25) + 
    coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + scale_y_reverse() + 
    stat_density2d(mapping= aes(alpha = ..level..), geom="polygon", bins=3, size=1) 

Immaginate io uso questo stesso codice, ma '' this_df modifiche su ogni fotogramma. Quindi in un grafico, forse la densità varia da 0 a 4e-4. Su un altro, la densità varia da 0 a 4e-2.

Per impostazione predefinita, ggplot calcolerà una densità distinta -> mappatura del colore per ciascuno di questi. Ma questo significherebbe che i due grafici - i due fotogrammi dell'animazione - non sono davvero comparabili. Se questo fosse un grafico dell'istogramma o della densità, farei semplicemente una chiamata a coord_cartesian e cambi il x e y lim. Ma per la trama della densità, non ho idea di come cambiare la scala.

Il più vicino che ho trovato è questo:

Overlay two ggplot2 stat_density2d plots with alpha channels

Ma non hanno la possibilità di mettere i due lotti di densità sullo stesso grafico, dal momento che voglio che siano fotogrammi distinti.

Qualsiasi aiuto sarebbe molto apprezzato!

EDIT:

Ecco un esempio riproducibile:

set.seed(4) 
g = list(NA,NA) 
for (i in 1:2) { 

    sdev = runif(1) 
    X = rnorm(1000, mean = 512, sd= 300*sdev) 
    Y = rnorm(1000, mean = 384, sd= 200*sdev) 

    this_df = as.data.frame(cbind(X = X,Y = Y, condition = 1:2)) 

    g[[i]] = ggplot(data= this_df, aes(x=X, y=Y)) + 
    geom_point(aes(color= as.factor(condition)), alpha= .25) + 
    coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + scale_y_reverse() + 
    stat_density2d(mapping= aes(alpha = ..level.., color= as.factor(condition)), geom="contour", bins=4, size= 2) 

} 
print(g) # level has a different scale for each 
+0

Stai mappando 'alpha' sul livello, non sul colore. Puoi controllare la scala alfa aggiungendo 'scale_alpha_continuous (limits = ...)' dove 'limits' è un vettore che specifica i limiti in unità di' ..level..', quindi (0,4e-2) suppongo. Se fornisci il tuo set di dati, qualcuno potrebbe essere disposto a darti più aiuto. – jlhoward

+0

Grazie per la risposta! Ho aggiunto codice riproducibile con dati falsi (non posso condividere i dati reali). Notate che se aggiungete, diciamo '+ scale_alpha_continuous (limits = c (0, 2e-6))' alla fine di questo codice, rende continuo il ridimensionamento alfa, ma NON aggiusta i contorni. Come posso rendere il ridimensionamento del contorno coerente tra i due grafici? – jwdink

+0

Stai dicendo che vuoi tracciare contorni per gli stessi valori di .. livello ... in entrambi i grafici? Se è così, allora usa 'breaks = ...' in 'stat_density2d (...)'. – jlhoward

risposta

7

in modo da avere entrambi i grafici mostrano i contorni con gli stessi livelli, utilizzare l'argomento breaks=... in stat_densit2d(...). Per avere entrambi i grafici con la stessa mappatura di alpha a livello, utilizzare scale_alpha_continuous(limits=...).

Ecco il codice completo per dimostrare:

library(ggplot2) 
set.seed(4) 
g = list(NA,NA) 
for (i in 1:2) { 
    sdev = runif(1) 
    X = rnorm(1000, mean = 512, sd= 300*sdev) 
    Y = rnorm(1000, mean = 384, sd= 200*sdev) 
    this_df = as.data.frame(cbind(X = X,Y = Y, condition = 1:2)) 

    g[[i]] = ggplot(data= this_df, aes(x=X, y=Y)) + 
    geom_point(aes(color= as.factor(condition)), alpha= .25) + 
    coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + scale_y_reverse() + 
    stat_density2d(mapping= aes(alpha = ..level.., color= as.factor(condition)), 
        breaks=1e-6*seq(0,10,by=2),geom="contour", bins=4, size= 2)+ 
    scale_alpha_continuous(limits=c(0,1e-5))+ 
    scale_color_discrete("Condition") 
} 
library(gridExtra) 
do.call(grid.arrange,c(g,ncol=2)) 

E il risultato ...

+1

Questa è la soluzione di cui avevo bisogno oggi. Ho eseguito il codice e ho scoperto che 'stat_density2d' non sta prendendo' breaks' con ggplot2 corrente (ggplot2_2.1.0). Riesci a pensare ad un altro modo per ottenere lo stesso effetto? – jazzurro

7

Vorrei lasciare un aggiornamento per questa domanda. A partire da luglio 2016, stat_density2d non sta più prendendo breaks. Per riprodurre l'immagine, è necessario spostare breaks=1e-6*seq(0,10,by=2) a scale_alpha_continuous().

set.seed(4) 
g = list(NA,NA) 
for (i in 1:2) { 
    sdev = runif(1) 
    X = rnorm(1000, mean = 512, sd= 300*sdev) 
    Y = rnorm(1000, mean = 384, sd= 200*sdev) 
    this_df = as.data.frame(cbind(X = X,Y = Y, condition = 1:2)) 

g[[i]] = ggplot(data= this_df, aes(x=X, y=Y)) + 
     geom_point(aes(color= as.factor(condition)), alpha= .25) + 
     coord_cartesian(ylim= c(0, 768), xlim= c(0,1024)) + 
     scale_y_reverse() + 
     stat_density2d(mapping= aes(alpha = ..level.., color= as.factor(condition)), 
     geom="contour", bins=4, size= 2) + 
     scale_alpha_continuous(limits=c(0,1e-5), breaks=1e-6*seq(0,10,by=2))+ 
     scale_color_discrete("Condition") 
    } 

do.call(grid.arrange,c(g,ncol=2))