Wie kann ich ein "unausgeglichenes" Gitter von ggplots erhalten?

94

Mit grid.arrangekann ich mehrere ggplotFiguren in einem Raster anordnen , um eine Figur mit mehreren Feldern zu erhalten, indem ich Folgendes verwende:

library(ggplot2)
library(grid)
library(gridExtra)

Generieren Sie dann einige ggplot2-Diagramme

plot5 <- grid.arrange(plot4, plot1, heights=c(3/4, 1/4), ncol=1, nrow=2)

Wie kann ich ein "unausgeglichenes" 2-Spalten-Layout mit einem Diagramm in der gesamten ersten Spalte und drei Diagrammen in der zweiten Spalte erhalten? Ich spielte mit einem "Grid-of-Grids" -Ansatz, indem ich versuchte, grid.arrangeein Gitter (z. B. plot5oben) gegen ein anderes Diagramm zu zeichnen, erhielt jedoch Folgendes:

Fehler in arrangGrob (..., as.table = as.table, clip = clip, main = main ,: Eingabe muss grobs sein!

Aktualisieren:

Danke für den Hinweis. Ich werde in viewportsund schauen grid. In der Zwischenzeit hat die layOutFunktion im 'wq'-Paket dank @DWin für die Kompilierungsfigur in meinem SweaveDokument sehr gut funktioniert : Geben Sie hier die Bildbeschreibung ein

Update 2:

Der arrangeGrobBefehl (wie von @baptiste vorgeschlagen) funktioniert ebenfalls gut und scheint sehr intuitiv zu sein - zumindest war es einfach, die Breite der beiden Spalten zu ändern. Es hat auch den Vorteil, dass das `wq'-Paket nicht benötigt wird.

zB Hier ist der Code aus meiner Sweave-Datei:

<<label=fig5plot, echo=F, results=hide>>=
plot5<-grid.arrange(plot4, arrangeGrob(plot1, plot2, plot3, ncol=1), 
                    ncol=2, widths=c(1,1.2))
@
\begin{figure}[]
    \begin{center}
<<label=fig5,fig=TRUE,echo=T, width=10,height=12>>=
<<fig5plot>>
@
\end{center}
\caption{Combined plots using the `arrangeGrob' command.}
\label{fig:five}
\end{figure}

welches die folgende Ausgabe erzeugt: Geben Sie hier die Bildbeschreibung ein

Übrigens, sagt mir jemand, warum die '> NA' erscheint?

user441706
quelle
Möglicherweise müssen Sie die Ansichtsfenster selbst einrichten - grid.arrangemöglicherweise nicht flexibel genug (Stackoverflow nach "[r] grid viewport" durchsuchen)
Ben Bolker,
2
@BenBolker Hat dich mit in eine fruchtbare Richtung gelenkt grid. Siehe auch Hadleys ggplot2-Buch, Abschnitt 8.4.2.
Ari B. Friedman
1
@BenBolker grid.arrangekann mit verschachtelten Ansichtsfenstern unter Verwendung seines Begleiters verwendet werden arrangeGrob(im Wesentlichen wird a zurückgegeben gTree), wie im folgenden Beispiel.
Taufe
1
Ihre endgültige Zuordnung zu plot5ist nicht erforderlich, da grid.arrangenichts zurückgegeben wird (NULL). Wenn Sie den resultierenden Grob speichern möchten, verwenden Sie ihn arrangeGroberneut (und grid.drawzeigen Sie ihn an).
Baptiste

Antworten:

73

grid.arrangezeichnet direkt auf das Gerät; Wenn Sie es mit anderen Rasterobjekten kombinieren möchten, die Sie benötigen arrangeGrob, wie in

 p = rectGrob()
 grid.arrange(p, arrangeGrob(p,p,p, heights=c(3/4, 1/4, 1/4), ncol=1),
              ncol=2)

Bearbeiten (07/2015): Mit v> 2.0.0 können Sie das layout_matrixArgument verwenden,

 grid.arrange(p,p,p,p, layout_matrix = cbind(c(1,1,1), c(2,3,4)))
Baptiste
quelle
6
Könnten Sie erklären, wie die cbind(c(1,1,1), c(2,3,4)) Matrix die Anordnung der Figuren beschreibt?
Ron Gejman
5
@ RonGejman Es ist einfach, wenn Sie die 3x2-Matrix auf dem Bildschirm drucken: Die erste Spalte enthält alle Einsen. Dort befindet sich der erste Plot, der sich über die drei Zeilen erstreckt. Die zweite Spalte enthält die Diagramme 2, 3, 4, die jeweils eine Zeile belegen.
Baptiste
17

Ich habe versucht, es mit einem Raster herauszufinden, und dachte, ich hätte es nicht geschafft, aber es ist fehlgeschlagen (obwohl ich jetzt den Code in der unten zitierten Funktion betrachte, kann ich sehen, dass ich wirklich nah dran war ... :-)

Das 'wq'-Paket hat eine layOut Funktion, die es für Sie :

p1 <- qplot(mpg, wt, data=mtcars)
layOut(list(p1, 1:3, 1),   # takes three rows and the first column
        list(p1, 1, 2),    # next three are on separate rows
         list(p1, 2,2), 
          list(p1, 3,2))

Geben Sie hier die Bildbeschreibung ein

IRTFM
quelle
Wow, das ist eine nützliche Funktion! Ich denke, Copy + Paste hat Sie jedoch möglicherweise gescheitert. meinte sie g1, g2usw. zu allen sein p1?
Joran
3
@joran: Ich habe. Ich kann mich nicht erinnern, welche der "drei Tugenden des Programmierens" Faulheit ist, aber ich weiß, dass es irgendwo etwas gibt.
IRTFM
Vielen Dank! Hat sehr gut funktioniert. Siehe oben.
user441706
2

Eine weitere Alternative ist das patchworkPaket von Thomas Lin Pedersen.

# install.packages("devtools")
# devtools::install_github("thomasp85/patchwork")
library(patchwork)

Generieren Sie einige Diagramme.

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp)) + facet_grid(rows = vars(gear))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
p3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
p4 <- ggplot(mtcars) + geom_bar(aes(carb))

Ordnen Sie nun die Grundstücke an.

p1 + (p2 / p3 / p4)

Geben Sie hier die Bildbeschreibung ein

Markus
quelle
1

Es gibt auch ein Multipanelfigure-Paket , das es wert ist, erwähnt zu werden. Siehe auch diese Antwort .

library(ggplot2)
theme_set(theme_bw())

q1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
q2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))
q3 <- ggplot(mtcars) + geom_smooth(aes(disp, qsec))
q4 <- ggplot(mtcars) + geom_bar(aes(carb))

library(magrittr)
library(multipanelfigure)

figure1 <- multi_panel_figure(columns = 2, rows = 3, panel_label_type = "upper-roman")

figure1 %<>%
  fill_panel(q1, column = 1, row = 1:3) %<>%
  fill_panel(q2, column = 2, row = 1) %<>%
  fill_panel(q3, column = 2, row = 2) %<>%
  fill_panel(q4, column = 2, row = 3)
#> `geom_smooth()` using method = 'loess' and formula 'y ~ x'
figure1

Erstellt am 2018-07-16 vom reprex-Paket (v0.2.0.9000).

Tung
quelle