2012-10-31 7 views
11

Vorrei utilizzare lo stat_binhex() di ggplot2 per tracciare contemporaneamente due variabili indipendenti sullo stesso grafico, ciascuna con il proprio gradiente di colore utilizzando scale_colour_gradientn().ggplot2 più diagrammi stat_binhex() con sfumature di colore diverse in un'immagine

Se ignoriamo il fatto che le unità dell'asse x non corrispondono, un esempio riproducibile sarebbe quello di tracciare quanto segue nella stessa immagine mantenendo gradienti di riempimento separati.

d <- ggplot(diamonds, aes(x=carat,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA) 
try(ggsave(plot=d,filename=<some file>,height=6,width=8)) 

enter image description here

d <- ggplot(diamonds, aes(x=depth,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA) 
try(ggsave(plot=d,filename=<some other file>,height=6,width=8)) 

enter image description here

ho trovato qualche conversazione di un problema correlato in gruppi ggplot2 google here.

risposta

10

Ecco un'altra soluzione possibile: ho preso @ idea di mappatura bin mnel contare fino a trasparenza alfa, e ho trasformato le variabili X in modo che possano essere tracciate sugli stessi assi.

library(ggplot2) 

# Transforms range of data to 0, 1. 
rangeTransform = function(x) (x - min(x))/(max(x) - min(x)) 

dat = diamonds 
dat$norm_carat = rangeTransform(dat$carat) 
dat$norm_depth = rangeTransform(dat$depth) 

p1 = ggplot(data=dat) + 
    theme_bw() + 
    stat_binhex(aes(x=norm_carat, y=price, alpha=..count..), fill="#002BFF") + 
    stat_binhex(aes(x=norm_depth, y=price, alpha=..count..), fill="#FFD500") + 
    guides(fill=FALSE, alpha=FALSE) + 
    xlab("Range Transformed Units") 

ggsave(plot=p1, filename="plot_1.png", height=5, width=5) 

Pensieri:

  1. ho cercato (e fallito) per visualizzare una legenda dei colori sensibile/alfa.Sembra difficile, ma dovrebbe essere possibile considerando tutte le caratteristiche di personalizzazione della leggenda di ggplot2.

  2. L'etichettatura delle unità dell'asse X richiede un qualche tipo di soluzione. Tracciare due insiemi di unità su un asse è sfigurato da molti e ggplot2 non ha questa caratteristica.

  3. L'interpretazione di celle con colori sovrapposti sembra abbastanza chiara in questo esempio, ma potrebbe diventare molto caotica a seconda dei set di dati utilizzati e dei colori scelti.

  4. Se i due colori sono complementi additivi, quindi ovunque si sovrappongano allo stesso modo, si vedrà un grigio neutro. Dove la sovrapposizione non è uguale, il grigio passerebbe a più giallo o più blu. I miei colori non sono abbastanza complementari, a giudicare dal colore leggermente rosa delle celle di sovrapposizione grigie.

enter image description here

+0

Questa è la direzione giusta. Qualche idea su come assegnare un scale_fill_gradientn() a ogni stat_binhex()? Inoltre, il pensiero n. 2 ha debitamente preso atto: la mia applicazione prevista utilizza la stessa unità per entrambe le variabili x – metasequoia

+0

È possibile avere solo una scala 'fill' in ogni chiamata' ggplot'. Posso immaginare un qualche tipo di hack in cui si definisce 'scale_fill_manual' con colori specificati manualmente per ciascuna combinazione di intervallo di valori * variabile. Quindi, ogni chiamata a 'stat_binhex' mapperebbe' fill' su un fattore specifico della variabile ... ma ora sto solo balbettando ... – bdemarest

5

Penso che quello che vuoi va contro i principi di ggplot2 e la grammatica della grafica si avvicina più in generale. Fino a quando il issue è indirizzata (per la quale non vorrei trattenere il fiato), avete un paio di scelte

Usa facet_wrap e alpha

Questo non produrrà un bel leggenda , ma ti porta in qualche modo a ciò che vuoi.

È possibile impostare il valore alpha per scalare dal calcolato Frequency, accessibile da ..Frequency..

Non credo che è possibile unire le leggende bene però.

library(reshape2) 
# in long format 
dm <- melt(diamonds, measure.var = c('depth','carat')) 

ggplot(dm, aes(y = price, fill = variable, x = value)) + 
    facet_wrap(~variable, ncol = 1, scales = 'free_x') + 
    stat_binhex(aes(alpha = ..count..), colour = 'grey80') + 
    scale_alpha(name = 'Frequency', range = c(0,1)) + 
    theme_bw() + 
    scale_fill_manual('Variable', values = setNames(c('darkblue','yellow4'), c('depth','carat'))) 

enter image description here

Usa gridExtra con grid.arrange o arrangeGrob

È possibile creare trame distinte e utilizzare gridExtra::grid.arrange di organizzare su una singola immagine.

d_carat <- ggplot(diamonds, aes(x=carat,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("white","blue"),name = "Frequency",na.value=NA) 

d_depth <- ggplot(diamonds, aes(x=depth,y=price))+ 
    stat_binhex(colour="white",na.rm=TRUE)+ 
    scale_fill_gradientn(colours=c("yellow","black"),name = "Frequency",na.value=NA) 

library(gridExtra) 


grid.arrange(d_carat, d_depth, ncol =1) 

enter image description here

Se si desidera che questo lavorare con ggsave (grazie a @bdemarest commento qui sotto e @baptiste)

sostituire grid.arrange con arrangeGrob qualcosa di simile.

ggsave(plot=arrangeGrob(d_carat, d_depth, ncol=1), filename="plot_2.pdf", height=12, width=8) 
+2

È possibile utilizzare 'ggsave()' 'se si sostituisce arrangeGrob' per' grid.arrange'. Ad esempio: 'ggsave (plot = organizzGrob (d_carat, d_depth, ncol = 1), filename =" plot_2.pdf ", height = 12, width = 8)'. (@baptiste me lo ha fatto notare in un precedente commento). – bdemarest

+0

Grazie a @bdemarest, molto utile. – mnel

+0

La prima risposta potrebbe non funzionare più sulla versione più recente di ggplot, vedere [qui] (https://stackoverflow.com/questions/39446852/geom-hexbin-map-bincount-to-alpha/). – Axeman

Problemi correlati