web-dev-qa-db-fra.com

Aligner à gauche deux bords du graphique (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 graphiques soient alignés ainsi que les bords droits, quelles que soient les étiquettes des axes. (Le problème se pose parce que les étiquettes d’un graphique sont courtes et que l’autre est longue).

La question:
Comment puis-je faire ceci? Je ne suis pas marié à grid.arrange mais le ggplot2 est un must. 

Ce que j'ai essayé:
J'ai essayé de jouer avec les largeurs et les hauteurs ainsi qu'avec ncol et nrow pour créer une grille 2 x 2 et placer les visuels dans des coins opposés, puis jouer avec les largeurs, mais je ne pouvais pas les obtenir dans des 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

96
Tyler Rinker

Essaye ça,

 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 un nombre quelconque de parcelles) en utilisant une version modifiée de rbind.gtable incluse dans gridExtra

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

Je voulais généraliser cela pour n'importe quel nombre de parcelles. Voici une solution étape par étape utilisant l'approche de Baptiste:

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

collecter les largeurs pour chaque graob de chaque parcelle

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

utilisez do.call pour obtenir la largeur maximale

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

assigne la largeur maximale à chaque grob

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

plot

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

Utilisation de 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
zx8754

Sur http://rpubs.com/MarkusLoew/13295 est une solution vraiment facile disponible (dernier élément).

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'))
12
Wilbert

Voici une autre solution possible 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
bdemarest

Le paquetage Egg encapsule les objets ggplot dans un gtable 3x3 normalisé, permettant ainsi l'alignement des panneaux de traçage 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
baptiste

Je sais que ce message est ancien 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 joli:

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

Au mieux, c'est un hack:

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

Cela semble vraiment faux.

0
Tyler Rinker