aligner à gauche deux bords de graphe (ggplot)

j'utilise ggplot et j'ai deux graphiques que je veux afficher l'un sur l'autre. J'ai utilisé grid.arrange de gridExtra pour les empiler. Le problème est que je veux que les bords gauches des graphes s'alignent aussi bien que les bords droits indépendamment des étiquettes d'axe. (le problème se pose parce que les étiquettes d'un graphe sont courts tandis que l'autre est long).

La Question:

Comment puis-je faire cela? Je ne suis pas marié à la grille.organiser mais le ggplot2 est un must.

Ce que j'ai essayé:

J'ai essayé de jouer avec les largeurs et les hauteurs ainsi que ncol et nrow pour faire une grille de 2 x 2 et placer les visuels dans les coins opposés et ensuite jouer avec les largeurs, mais je ne pouvais pas obtenir les visuels dans les coins opposés.

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)

enter image description here

91
demandé sur baptiste 2012-11-08 21:59:36

8 réponses

Essayez cette,

 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)

Modifier

Voici une solution plus générale (fonctionne avec n'importe quel nombre de parcelles) en utilisant une version modifiée de rbind.gtable inclus dans gridExtra

gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))
116
répondu baptiste 2016-06-13 00:01:09

je voulais généraliser ceci pour n'importe quel nombre de parcelles. Voici une solution étape par étape en utilisant L'approche de Baptiste:

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

collecter les largeurs pour chaque grob de chaque parcelle

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

utiliser do.appel pour obtenir la largeur maximale

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

asign la largeur maximale à chaque grob

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

parcelle

do.call("grid.arrange", c(grobs, ncol = 1))
31
répondu slizb 2013-10-11 16:18:12

utilisant cowplot package:

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")

enter image description here

22
répondu zx8754 2015-10-01 07:45:01

sur http://rpubs.com/MarkusLoew/13295 est une solution vraiment facile disponible (dernier article) Appliqué à ce problème:

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"))

vous pouvez également l'utiliser pour la largeur et la hauteur:

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'))
11
répondu Wilbert 2014-04-10 10:06:55

Voici une autre solution possible en utilisant melt du paquet reshape2, et 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)

enter image description here

8
répondu bdemarest 2012-11-08 20:52:39

le paquet egg enroule les objets ggplot dans un 3x3 gtable standardisé, permettant l'alignement des panneaux de placage entre des ggplots arbitraires, y compris ceux à facettes.

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)

enter image description here

7
répondu baptiste 2016-06-13 00:24:49

au mieux, c'est un piratage:

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

Il se sent vraiment mal.

0
répondu Tyler Rinker 2012-11-08 18:14:27

je sais que c'est un vieux post, et qu'il a déjà été répondu, mais puis-je suggérer de combiner l'approche de @baptiste avec purrr pour le rendre plus beau:

library(purrr)
list(A, B) %>% 
  map(ggplotGrob) %>% 
  do.call(gridExtra::gtable_rbind, .) %>% 
  grid::grid.draw()
0
répondu Felipe Gerard 2018-07-11 16:35:05