449 Stimmen

Seite-an-Seite-Diagramme mit ggplot2

Ich möchte zwei Parzellen nebeneinander platzieren, indem ich die ggplot2-Paket , d.h. das Äquivalent von par(mfrow=c(1,2)) .

Ich möchte z. B. die folgenden beiden Diagramme mit demselben Maßstab nebeneinander anzeigen lassen.

x <- rnorm(100)
eps <- rnorm(100,0,.2)
qplot(x,3*x+eps)
qplot(x,2*x+eps)

Muss ich sie in denselben data.frame einfügen?

qplot(displ, hwy, data=mpg, facets = . ~ year) + geom_smooth()

627voto

David LeBauer Punkte 29881

Beliebige ggplots nebeneinander (oder n Plots auf einem Raster)

Die Funktion grid.arrange() im gridExtra Paket werden mehrere Grundstücke kombiniert; so können Sie zwei nebeneinander stellen.

require(gridExtra)
plot1 <- qplot(1)
plot2 <- qplot(1)
grid.arrange(plot1, plot2, ncol=2)

Dies ist nützlich, wenn die beiden Diagramme nicht auf denselben Daten basieren, z. B. wenn Sie verschiedene Variablen darstellen wollen, ohne reshape() zu verwenden.

Dadurch wird die Ausgabe als Nebeneffekt gezeichnet. Um den Seiteneffekt in eine Datei zu drucken, geben Sie einen Gerätetreiber an (z. B. pdf , png , usw.), z.B.

pdf("foo.pdf")
grid.arrange(plot1, plot2)
dev.off()

oder verwenden Sie arrangeGrob() in Verbindung mit ggsave() ,

ggsave("foo.pdf", arrangeGrob(plot1, plot2))

Dies entspricht der Erstellung von zwei verschiedenen Plots mit par(mfrow = c(1,2)) . Dies spart nicht nur Zeit bei der Anordnung der Daten, sondern ist auch notwendig, wenn Sie zwei unterschiedliche Darstellungen wünschen.


Anhang: Verwendung von Facetten

Facetten sind hilfreich, um ähnliche Darstellungen für verschiedene Gruppen zu erstellen. Darauf wird in vielen Antworten weiter unten hingewiesen, aber ich möchte diesen Ansatz mit Beispielen hervorheben, die den obigen Diagrammen entsprechen.

mydata <- data.frame(myGroup = c('a', 'b'), myX = c(1,1))

qplot(data = mydata, 
    x = myX, 
    facets = ~myGroup)

ggplot(data = mydata) + 
    geom_bar(aes(myX)) + 
    facet_wrap(~myGroup)

Update

die plot_grid Funktion in der cowplot lohnt sich als Alternative zu grid.arrange . Siehe die Antwort von @claus-wilke unten und diese Vignette für einen gleichwertigen Ansatz; die Funktion ermöglicht jedoch eine feinere Steuerung von Lage und Größe der Fläche auf der Grundlage von diese Vignette .

261voto

Claus Wilke Punkte 15374

Ein Nachteil der Lösungen, die auf grid.arrange ist, dass sie die Kennzeichnung der Parzellen mit Buchstaben (A, B usw.), wie sie in den meisten Zeitschriften verlangt wird, erschweren.

Ich habe die Kuhplot Paket, um dieses (und ein paar andere) Probleme zu lösen, insbesondere die Funktion plot_grid() :

library(cowplot)

iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot() + theme_bw()

iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.7) + theme_bw() +
  theme(legend.position = c(0.8, 0.8))

plot_grid(iris1, iris2, labels = "AUTO")

enter image description here

Das Objekt, das plot_grid() zurückgibt, ist ein weiteres ggplot2-Objekt, und Sie können es mit ggsave() wie immer:

p <- plot_grid(iris1, iris2, labels = "AUTO")
ggsave("plot.pdf", p)

Alternativ können Sie auch die Funktion cowplot verwenden save_plot() , die eine dünne Hülle um ggsave() die es einfach macht, die richtigen Dimensionen für kombinierte Plots zu erhalten, z. B.:

p <- plot_grid(iris1, iris2, labels = "AUTO")
save_plot("plot.pdf", p, ncol = 2)

(Die ncol = 2 Argument sagt save_plot() dass zwei Grundstücke nebeneinander liegen, und save_plot() macht das gespeicherte Bild doppelt so breit).

Eine ausführlichere Beschreibung der Anordnung von Plots in einem Raster finden Sie unter diese Vignette. Es gibt auch eine Vignette, die erklärt, wie man Plots mit einer gemeinsame Legende.

Ein häufiger Punkt der Verwirrung ist, dass das cowplot-Paket das Standardthema von ggplot2 ändert. Das Paket verhält sich so, weil es ursprünglich für interne Laborzwecke geschrieben wurde und wir das Standardthema nie verwenden. Wenn dies Probleme verursacht, können Sie einen der folgenden drei Ansätze verwenden, um sie zu umgehen:

1. Legen Sie das Thema manuell für jedes Grundstück fest. Ich halte es für eine gute Praxis, immer ein bestimmtes Thema für jede Handlung festzulegen, so wie ich es bei + theme_bw() im obigen Beispiel. Wenn Sie ein bestimmtes Thema angeben, spielt das Standardthema keine Rolle.

2. Kehren Sie das Standardthema zum Standardthema von ggplot2 zurück. Sie können dies mit einer Zeile Code tun:

theme_set(theme_gray())

3. Rufen Sie die cowplot-Funktionen auf, ohne das Paket anzuhängen. Sie können auch nicht anrufen library(cowplot) o require(cowplot) und rufen stattdessen Cowplot-Funktionen auf, indem sie cowplot:: . Das obige Beispiel mit dem Standard-Theme von ggplot2 würde z.B. so aussehen:

## Commented out, we don't call this
# library(cowplot)

iris1 <- ggplot(iris, aes(x = Species, y = Sepal.Length)) +
  geom_boxplot()

iris2 <- ggplot(iris, aes(x = Sepal.Length, fill = Species)) +
  geom_density(alpha = 0.7) +
  theme(legend.position = c(0.8, 0.8))

cowplot::plot_grid(iris1, iris2, labels = "AUTO")

enter image description here

Aktualisierungen:

  • Seit cowplot 1.0 wird das Standard ggplot2-Theme nicht mehr verändert.
  • Ab ggplot2 3.0.0 können Plots direkt beschriftet werden, siehe z.B. hier.

95voto

Deena Punkte 5265

Die Verwendung des Patchwork Paket, können Sie einfach + Betreiber:

library(ggplot2)
library(patchwork)

p1 <- ggplot(mtcars) + geom_point(aes(mpg, disp))
p2 <- ggplot(mtcars) + geom_boxplot(aes(gear, disp, group = gear))

p1 + p2

patchwork

Andere Betreiber sind / zum Stapeln von Plots, um Plots nebeneinander zu platzieren, und () um Elemente zu gruppieren. Sie können zum Beispiel eine obere Reihe mit 3 Plots und eine untere Reihe mit einem Plot konfigurieren mit (p1 | p2 | p3) /p . Weitere Beispiele finden Sie in der Paketdokumentation .

53voto

David LeBauer Punkte 29881

Sie können Folgendes verwenden multiplot Funktion von Das R-Kochbuch von Winston Chang

multiplot(plot1, plot2, cols=2)

multiplot <- function(..., plotlist=NULL, cols) {
    require(grid)

    # Make a list from the ... arguments and plotlist
    plots <- c(list(...), plotlist)

    numPlots = length(plots)

    # Make the panel
    plotCols = cols                          # Number of columns of plots
    plotRows = ceiling(numPlots/plotCols) # Number of rows needed, calculated from # of cols

    # Set up the page
    grid.newpage()
    pushViewport(viewport(layout = grid.layout(plotRows, plotCols)))
    vplayout <- function(x, y)
        viewport(layout.pos.row = x, layout.pos.col = y)

    # Make each plot, in the correct location
    for (i in 1:numPlots) {
        curRow = ceiling(i/plotCols)
        curCol = (i-1) %% plotCols + 1
        print(plots[[i]], vp = vplayout(curRow, curCol ))
    }

}

19voto

Dirk Eddelbuettel Punkte 345316

Ja, ich denke, Sie müssen Ihre Daten entsprechend anordnen. Eine Möglichkeit wäre die folgende:

X <- data.frame(x=rep(x,2),
                y=c(3*x+eps, 2*x+eps),
                case=rep(c("first","second"), each=100))

qplot(x, y, data=X, facets = . ~ case) + geom_smooth()

Ich bin mir sicher, dass es bessere Tricks in Plyr oder Reshape gibt - ich bin noch nicht wirklich auf dem Laufenden mit all diesen leistungsstarken Paketen von Hadley.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X