2011-08-19 4 views
14

Contesto

Voglio tracciare due ggplot2 sulla stessa pagina con la stessa legenda. http://code.google.com/p/gridextra/wiki/arrangeGrob descrive come farlo. Questo sembra già buono. Ma ... Nel mio esempio ho due trame con lo stesso asse xe un diverso asse y. Quando l'intervallo dell'asse y è almeno 10 volte superiore a quello dell'altro grafico (ad esempio 10000 anziché 1000), ggplot2 (o griglia?) Non allinea correttamente i grafici (vedere Output sotto).Allinea più diagrammi ggplot2 con griglia

Domanda

Come faccio anche allineare il lato sinistro del grafico, utilizzando due diversi asse y?

Esempio di codice

x = c(1, 2) 
y = c(10, 1000) 
data1 = data.frame(x,y) 
p1 <- ggplot(data1) + aes(x=x, y=y, colour=x) + geom_line() 

y = c(10, 10000) 
data2 = data.frame(x,y) 
p2 <- ggplot(data2) + aes(x=x, y=y, colour=x) + geom_line() 


# Source: http://code.google.com/p/gridextra/wiki/arrangeGrob 
leg <- ggplotGrob(p1 + opts(keep="legend_box")) 
legend=gTree(children=gList(leg), cl="legendGrob") 
widthDetails.legendGrob <- function(x) unit(3, "cm") 
grid.arrange(
    p1 + opts(legend.position="none"), 
    p2 + opts(legend.position="none"), 
    legend=legend, main ="", left = "") 

uscita

Example image

+1

Vedere: http://stackoverflow.com/questions/13294952/left-align-two-g raph-edges-ggplot/13295880 # 13295880? –

risposta

7

Se non ti dispiace un kludge spudorata, basta aggiungere un carattere in più per l'etichetta più lunga p1, in questo modo:

p1 <- ggplot(data1) + 
    aes(x=x, y=y, colour=x) + 
    geom_line() + 
    scale_y_continuous(breaks = seq(200, 1000, 200), 
         labels = c(seq(200, 800, 200), " 1000")) 

Ho due domande di base , che spero perdonerai se hai i tuoi motivi:

1) Perché non utilizzare lo stesso asse y su entrambi? Ritengo che sia un approccio più diretto e facilmente raggiunto nel tuo esempio precedente aggiungendo scale_y_continuous(limits = c(0, 10000)) a p1.

2) La funzionalità fornita da facet_wrap non è adeguata qui? E 'difficile sapere che cosa la vostra struttura dati è in realtà come, ma ecco un esempio di giocattoli di come farei questo:

library(ggplot2) 

# Maybe your dataset is like this 
x <- data.frame(x = c(1, 2), 
       y1 = c(0, 1000), 
       y2 = c(0, 10000)) 

# Molten data makes a lot of things easier in ggplot 
x.melt <- melt(x, id.var = "x", measure.var = c("y1", "y2")) 

# Plot it - one page, two facets, identical axes (though you could change them), 
# one legend 
ggplot(x.melt, aes(x = x, y = value, color = x)) + 
    geom_line() + 
    facet_wrap(~ variable, nrow = 2) 
+3

Accetto la faccetta sembra un'opzione migliore per l'esempio dato. Puoi anche aggiungere 'scale =" free_y "' se l'OP insiste sul fatto che le scale dell'asse y siano fatte indipendentemente. – joran

+0

Grazie @joran - non riuscivo a ricordare come farlo. –

+2

aggiungendo spazi nell'etichetta lavorati solo sull'output di sono. Una volta che l'ho eseguito tramite tikzdevice, gli spazi vengono ignorati. – apepper

10

un modo più pulito di fare la stessa cosa, ma in un modo più generico è quello di utilizzare il formattatore arg:

p1 <- ggplot(data1) + 
    aes(x=x, y=y, colour=x) + 
    geom_line() + 
    scale_y_continuous(formatter = function(x) format(x, width = 5)) 

fare lo stesso per il secondo lotto e assicurarsi di impostare la larghezza> = il numero più ampio che ci si aspetta in entrambe le trame.

+5

Nella mia versione di ggplot2, l'argomento era "[labels] (http://docs.ggplot2.org/current/scale_continuous.html)" e non "formatter". – simlmx

7

1. Usando cowplot pacchetto:

library(cowplot) 
plot_grid(p1, p2, ncol=1, align="v") 

enter image description here


2. Utilizzando tracks da ggbio pacchetto:

Nota: Sembra che ci sia un bug, le zecche x non si allineano. (testato il 17/03/2016, ggbio_1.18.5)

library(ggbio) 
tracks(data1=p1,data2=p2) 

enter image description here

0

La soluzione in ggbio per il vostro problema è quello di fissare le coordinate dell'asse x per le trame originali nel modo seguente:

library(ggbio) 
p1 <- f() 
fixed(p1) <- TRUE 
p2 <- f() 
fixed(p2) <- TRUE 
tracks(p1,p2) 

migliore,

Yatrosin