2016-01-08 2 views
6

Comincio dando il mio codice di esempio:Modifica 2 GEOMs stat_hex_bin ggplot2 separatamente

x <- runif(1000,0, 5) 
y <- c(runif(500, 0, 2), runif(500, 3,5)) 
A <- data.frame("X"=x,"Y"=y[1:500]) 
B <- data.frame("X"=x,"Y"=y[501:1000]) 
ggplot() + 
    stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) + 
    stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) + 
    scale_fill_continuous(low="red4", high="#ED1A3A") 

Produce il seguente grafico: enter image description here

Ora voglio gli esagoni inferiori a seguire una scala diversa. Vale a dire che vanno da un verde scuro a un verde più leggero. Come posso ottenerlo?

Aggiornamento: Come si può vedere dalle risposte finora, mi chiedo se c'è una soluzione senza l'utilizzo di scale alfa. Inoltre, l'utilizzo di due grafici senza margine o qualcosa di simile non è un'opzione per la mia specifica applicazione. Anche se sono entrambe risposte legittime :)

+0

Non dovrebbe essere 'stat_binhex()'? –

+0

Beh, entrambi i grafici sono esattamente gli stessi. Non sono sicuro se c'è una differenza oltre al nome. –

+1

'stat_bin_hex' non ha funzionato per me. Forse, ho una versione obsoleta di 'ggplot2' –

risposta

4

Piuttosto che cercare di ottenere due diverse scale di riempimento in una trama che si potrebbero alterare i colori dei valori più bassi, dopo la trama è stata costruita. L'idea di base è avere due grafici con le diverse scale di riempimento e quindi copiare alcuni dettagli da una trama all'altra.

# Base plot 
p <- ggplot() + 
    stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) + 
    stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) 

# Produce two plots with different fill colours 
p1 <- p + scale_fill_continuous(low="red4", high="#ED1A3A") 
p2 <- p + scale_fill_continuous(low="darkgreen", high="lightgreen") 

# Get fill colours for second plot and overwrite the corresponding 
# values in the first plot 
g1 <- ggplot_build(p1) 
g2 <- ggplot_build(p2) 
g1$data[[1]][,"fill"] <- g2$data[[1]][,"fill"] 

# You can draw this now but there is only one legend 
grid.draw(ggplot_gtable(g1)) 

Avere due leggende si possono unire le leggende dai due lotti insieme

# Bind the legends from the two plots together 
g1 <- ggplot_gtable(g1) 
g2 <- ggplot_gtable(g2) 

g1$grobs[[grep("guide", g1$layout$name)]] <- 
    rbind(g1$grobs[[grep("guide", g1$layout$name)]], 
     g2$grobs[[grep("guide", g2$layout$name)]]) 

grid.newpage() 
grid.draw(g1) 

Dare (da set.seed(10) prima generazione di dati)

enter image description here

+1

Ora è ancora meglio. Anche se è un po 'frustrante che non sia così naturale farlo. La maggior parte delle volte finisci per modificare i grobs. Buona risposta, darò qualche giorno in più alla domanda :) –

1

Un'alternativa, se vuoi più opzioni per giocare con i colori, basta creare due grafici e rimuovere tutto lo spazio tra i due grafici se combinato con grid.arrange().

p1 <- ggplot() + stat_bin_hex(data=B, aes(x=X, y=Y), bins=10) + 
    scale_fill_continuous(low="red4", high="#ED1A3A") + xlab("") + theme(axis.text.x=element_blank(), axis.ticks.x=element_blank(), plot.margin=unit(c(1,1,-0.5,1), "cm")) + scale_y_continuous(limits = c(2.5, 5.5)) 

p2 <- ggplot() + stat_bin_hex(data=A, aes(x=X, y=Y), bins=10) + scale_fill_continuous(low="darkgreen", high="green") + theme(plot.margin=unit(c(-0.5,1,1,1), "cm")) + scale_y_continuous(limits = c(-0.5, 2.5)) 

grid.arrange(p1,p2) 

enter image description here

+0

Non funziona per me. I dati nella mia applicazione sono i limiti superiori e inferiori di un intervallo di confidenza. Quindi devono essere tracciati entrambi nello stesso grafico:/ –

2

Questo dovrebbe fornire più o meno ciò che si vuole

ggplot() + 
    stat_bin_hex(data=A, aes(x=X, y=Y, alpha=..count..), bins=10,fill="green") + 
    stat_bin_hex(data=B, aes(x=X, y=Y, alpha=..count..), bins=10,fill="red") 

enter image description here

Per evitare che il grigio è inquietante a causa della alfa si poteva alla base del terreno con un'altra trama bianca nella stessa posizione e scurire un po 'i colori, come suggerito dal TO nei commenti

#just the red to show the impact due to scale_alpha 
ggplot() +scale_alpha_continuous(range=c(0.5,1))+ stat_bin_hex(data=A, aes(x=X, y=Y), bins=10,fill="white",show.legend = TRUE) + 
+  stat_bin_hex(data=A, aes(x=X, y=Y, alpha=..count..), bins=10,fill="red",show.legend = TRUE) + 
+  stat_bin_hex(data=B, aes(x=X, y=Y, alpha=..count..), bins=10,fill="green", show.legend=TRUE)+guides(fill=FALSE, alpha=FALSE) 

enter image description here

+0

Mi dispiace. Pensavo che questa soluzione sarebbe venuta fuori. Ho già giocato con esso. Ma il problema per me è che gli esagoni più leggeri non sono abbastanza visibili. E se uso 'scale_alpha_continuous (range = c (0.5,1)) "gli esagoni non sono abbastanza distinguibili (per i miei scopi). Quindi mi sono chiesto se esiste una soluzione "no alpha";) –

+0

Nessun problema. Mi rendo conto comunque che c'è un altro problema con esso. Le leggende sono un po 'incasinate. Ma dato che non è quello che vuoi, lo lascio qui, per evitare che altri lo provino. ;) – CAFEBABE

+0

in realtà aggiungo una brutta soluzione di hacking per quello in un secondo. – CAFEBABE