Ich verwende ggplot und habe zwei Grafiken, die ich übereinander anzeigen möchte. Ich habe grid.arrange
von gridExtra verwendet, um sie zu stapeln. Das Problem ist, ich möchte, dass die linken Kanten der Grafiken sowie die rechten Kanten unabhängig von den Achsenbeschriftungen ausgerichtet werden. (Das Problem entsteht, weil die Beschriftungen eines Diagramms kurz sind, während das andere Diagramm lang ist).
Die Frage:
Wie kann ich das machen? Ich bin nicht mit grid.arrange verheiratet, aber der ggplot2 ist ein Muss.
Was ich probiert habe:
Ich habe versucht, mit Breiten und Höhen sowie mit Ncol und Nrow zu spielen, um ein 2 x 2-Raster zu erstellen, die Visuals in gegenüberliegenden Ecken zu platzieren und dann mit den Breiten zu spielen, aber ich konnte die Visuals nicht in gegenüberliegenden Ecken finden.
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)
Versuche dies,
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)
Bearbeiten
Hier ist eine allgemeinere Lösung (funktioniert mit einer beliebigen Anzahl von Zeichnungen), die eine modifizierte Version von rbind.gtable
verwendet, die in gridExtra
enthalten ist.
gA <- ggplotGrob(A)
gB <- ggplotGrob(B)
grid::grid.newpage()
grid::grid.draw(rbind(gA, gB))
Ich wollte das für eine beliebige Anzahl von Plots verallgemeinern. Hier ist eine schrittweise Lösung mit dem Ansatz von Baptiste:
plots <- list(A, B, C, D)
grobs <- list()
widths <- list()
sammeln Sie die Breiten für jeden Grob jedes Plots
for (i in 1:length(plots)){
grobs[[i]] <- ggplotGrob(plots[[i]])
widths[[i]] <- grobs[[i]]$widths[2:5]
}
verwenden Sie do.call, um die maximale Breite zu erhalten
maxwidth <- do.call(grid::unit.pmax, widths)
weisen Sie jedem Grob die maximale Breite zu
for (i in 1:length(grobs)){
grobs[[i]]$widths[2:5] <- as.list(maxwidth)
}
plot
do.call("grid.arrange", c(grobs, ncol = 1))
Verwendung von 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")
Auf http://rpubs.com/MarkusLoew/13295 ist eine wirklich einfache Lösung verfügbar (letzter Punkt).
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"))
sie können dies auch für Breite und Höhe verwenden:
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'))
Hier ist eine weitere mögliche Lösung, die melt
aus dem Paket reshape2 und facet_wrap
verwendet:
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)
Das Paket Egg
umschließt ggplot-Objekte in eine standardisierte 3x3
-Tabelle, die die Ausrichtung von Diagrammfenstern zwischen beliebigen, auch facettierten, ggfs.
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)
Ich weiß, dass dies ein alter Beitrag ist, und dass er bereits beantwortet wurde. Ich kann jedoch vorschlagen, den Ansatz von @baptiste mit purrr
zu kombinieren, um ihn schöner zu gestalten:
library(purrr)
list(A, B) %>%
map(ggplotGrob) %>%
do.call(gridExtra::gtable_rbind, .) %>%
grid::grid.draw()
Am besten ist dies ein Hack:
library(wq)
layOut(list(A, 1, 2:16), list(B, 2:3, 1:16))
Es fühlt sich wirklich falsch an.