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)
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))
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))
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")
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'))
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)
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)
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()
Au mieux, c'est un hack:
library(wq)
layOut(list(A, 1, 2:16), list(B, 2:3, 1:16))
Cela semble vraiment faux.