sinistra allinea due bordi del grafico (ggplot)

Sto usando ggplot e ho due grafici che voglio visualizzare uno sopra l’altro. Ho usato grid.arrange da gridExtra per impilarli. Il problema è che voglio che i bordi a sinistra dei grafici siano allineati e quelli a destra indipendentemente dalle etichette degli assi. (il problema sorge perché le etichette di un grafico sono brevi mentre l’altra è lunga).

La domanda:
Come posso fare questo? Non sono sposato con grid.arrange ma il ggplot2 è un must.

Quello che ho provato:
Ho provato a giocare con larghezze e altezze oltre a ncol e nrow per creare una griglia 2 x 2 e posizionare la grafica negli angoli opposti e poi giocare con le larghezze ma non sono riuscito a ottenere la grafica negli angoli opposti.

 require(ggplot2);require(gridExtra) A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() grid.arrange(A, B, ncol=1) 

inserisci la descrizione dell'immagine qui

Prova questo,

  gA <- ggplotGrob(A) gB <- ggplotGrob(B) maxWidth = grid::unit.pmax(gA$widths[2:5], gB$widths[2:5]) gA$widths[2:5] <- as.list(maxWidth) gB$widths[2:5] <- as.list(maxWidth) grid.arrange(gA, gB, ncol=1) 

modificare

Ecco una soluzione più generale (funziona con qualsiasi numero di grafici) utilizzando una versione modificata di rbind.gtable inclusa in gridExtra

 gA <- ggplotGrob(A) gB <- ggplotGrob(B) grid::grid.newpage() grid::grid.draw(rbind(gA, gB)) 

Volevo generalizzare questo per qualsiasi numero di grafici. Ecco una soluzione passo passo che utilizza l’approccio di Baptiste:

 plots <- list(A, B, C, D) grobs <- list() widths <- list() 

raccogliere le larghezze per ogni grinza di ogni trama

 for (i in 1:length(plots)){ grobs[[i]] <- ggplotGrob(plots[[i]]) widths[[i]] <- grobs[[i]]$widths[2:5] } 

usa do.call per ottenere la larghezza massima

 maxwidth <- do.call(grid::unit.pmax, widths) 

assegna la larghezza massima a ciascun grob

 for (i in 1:length(grobs)){ grobs[[i]]$widths[2:5] <- as.list(maxwidth) } 

tracciare

 do.call("grid.arrange", c(grobs, ncol = 1)) 

Utilizzando il pacchetto cowplot :

 A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() library(cowplot) plot_grid(A, B, ncol=1, align="v") 

inserisci la descrizione dell'immagine qui

Su http://rpubs.com/MarkusLoew/13295 è una soluzione davvero semplice disponibile (ultimo elemento) applicata a questo problema:

 require(ggplot2);require(gridExtra) A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() grid.draw(rbind(ggplotGrob(A), ggplotGrob(B), size="first")) 

puoi anche usarlo per larghezza e altezza:

 require(ggplot2);require(gridExtra) A <- ggplot(CO2, aes(x=Plant)) + geom_bar() +coord_flip() B <- ggplot(CO2, aes(x=Type)) + geom_bar() +coord_flip() C <- ggplot(CO2, aes(x=conc)) + geom_bar() +coord_flip() D <- ggplot(CO2, aes(x=uptake)) + geom_bar() +coord_flip() grid.draw(cbind( rbind(ggplotGrob(A), ggplotGrob(B), size="first"), rbind(ggplotGrob(C), ggplotGrob(D), size="first"), size='first')) 

Ecco un’altra ansible soluzione che usa melt dal pacchetto facet_wrap e facet_wrap :

 library(ggplot2) library(reshape2) dat = CO2[, c(1, 2)] dat$id = seq(nrow(dat)) mdat = melt(dat, id.vars="id") head(mdat) # id variable value # 1 1 Plant Qn1 # 2 2 Plant Qn1 # 3 3 Plant Qn1 # 4 4 Plant Qn1 # 5 5 Plant Qn1 # 6 6 Plant Qn1 plot_1 = ggplot(mdat, aes(x=value)) + geom_bar() + coord_flip() + facet_wrap(~ variable, nrow=2, scales="free", drop=TRUE) ggsave(plot=plot_1, filename="plot_1.png", height=4, width=6) 

inserisci la descrizione dell'immagine qui

Il pacchetto egg avvolge gli oggetti ggplot in un 3x3 gtable standardizzato, consentendo l’allineamento dei pannelli di trama tra i ggplot arbitrari, inclusi quelli sfaccettati.

 library(egg) # devtools::install_github('baptiste/egg') library(ggplot2) p1 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() p2 <- ggplot(mtcars, aes(mpg, wt, colour = factor(cyl))) + geom_point() + facet_wrap( ~ cyl, ncol=2, scales = "free") + guides(colour="none") + theme() ggarrange(p1, p2) 

inserisci la descrizione dell'immagine qui

Nel migliore dei casi questo è un trucco:

 library(wq) layOut(list(A, 1, 2:16), list(B, 2:3, 1:16)) 

Sembra davvero sbagliato.

So che questo è un vecchio post, e che è già stato risposto, ma posso suggerire di combinare l’approccio di @ baptiste con purrr per renderlo più bello:

 library(purrr) list(A, B) %>% map(ggplotGrob) %>% do.call(gridExtra::gtable_rbind, .) %>% grid::grid.draw()