Zeichnen Sie mehrere Diagramme in einem Diagramm in R?

13

Mit dem folgenden Code habe ich versucht, vier Diagramme in einem Diagramm zu zeichnen R. Ich bin mit der Abbildung nicht zufrieden, da zwischen den Darstellungen viel Platz ist und daher die Breite der Darstellungen nicht ausreicht, um die Darstellungen zu analysieren.

  1. Könnte mir jemand helfen, eine schöne Grafik mit vier Plots zu erstellen?

  2. Wie kann ich x-Achsenbeschriftungen von 1 bis 10 anstatt der Standardbeschriftungen von 5 beibehalten?

Daten:

a1: 11,013, 13,814, 13,831, 13,714, 13,787, 13,734, 13,778, 13,771, 13,823, 13,659

a2: 5,181 7,747 8,314 8,061 7,920 8,153 8,540 8,845 7,881 8,301

Ich habe a1-Daten für b1, c1 und d1 verwendet. a2 Daten für b2, c2 und d2 nur für hier.

Zahl:

Bildbeschreibung hier eingeben

Code:

        op=par(mfrow=c(4,1), mar=c(5.5,5.1,4.1,2.1))
        plot(a1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="A")
        lines(a2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        par(xpd=T)
        legend(1,26.5,c("X","Y"),bty="n",horiz=T,cex=1.5,col=c("red1","darkblue"),text.col=c("red1","darkblue"),pch=c(1,3),lty=c(2,3),x.intersp=0.4,adj=0.2)
        plot(b1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="B")
        lines(b2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        plot(c1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="C")
        lines(c2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
        plot(d1/1000, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="D")
        lines(d2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
   > mtext("Price", side=2, at=100,line=3,cex=1.1)
Samarasa
quelle
1
Könnten Sie bitte die Details Ihrer Daten angeben? möglicherweise dput (data_from_r)
suncoolsu
@suncoolsu, ich habe die Frage mit einem Beispiel von Daten aktualisiert. Vielen Dank.
Samarasa
Was wäre, wenn Sie zwei Farben und vier Linientypen mit einer Legende auf denselben Achsen hätten? Ich möchte den Code und die Ergebnisse dafür sehen.
Paul
@ user87: Da 4 Parzellen aus 4 verschiedenen Experimenten stammen. Daher denke ich, dass es besser ist, 4 Diagramme zu zeichnen, um die Ergebnisse der Experimente zu analysieren.
Samarasa
@ user87, ich bin mir nicht sicher, was du meinst. Wenn Sie eine neue Frage stellen würden, würde diese möglicherweise jemand beantworten (ich würde :))
Brandon Bertelsen

Antworten:

16

Wenn Sie sich an die Methode halten möchten, die Sie verwendet haben, sollten Sie den Befehl layout () lernen. Ein paar weitere Detailänderungen und Sie können die Diagramme viel näher zusammen bekommen. Sie können auch die eindeutigen Elemente, die sich zwischen den Diagrammen ändern, in eine Liste einfügen (z. B. die Daten und Ränder) und dann eine Schleife durchlaufen. Sie werden auch feststellen, dass ich die untere Achse mit dem Befehl direct axis () erstellt habe, damit Sie steuern können, wohin die Elemente verschoben werden.

layout(matrix(1:5, ncol = 1), widths = 1,
        heights = c(1,5,5,5,7), respect = FALSE)
par(mar=c(0, 4, 0, 0))
plot(1, type = 'n', axes = FALSE, bty = 'n', ylab = '')
legend('left', , c("X","Y"), bty="n", horiz=T, cex=1.5, col=c("red1","darkblue"), text.col=c("red1","darkblue"), pch=c(1,3), lty=c(2,3), x.intersp=0.4,adj=0.2)
par(mar=c(0, 4, 2, 1), bty = 'o')
plot(a1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2, lwd=2.5, col="red1", lty=2, pch=1, main="A")
lines(a2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
par(xpd=T)
plot(b1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="B")
lines(b2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
plot(c1, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="C")
lines(c2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
par(mar=c(4, 4, 2, 1))
plot(d1/1000, type="b", ylim=c(0,14.5), xlab="Time (secs)", ylab="", xaxt = 'n', cex.axis=1.4, cex.lab=1.3,cex=1.2,lwd=2.5,col="red1",lty=2,pch=1, main="D")
lines(d2,type="b",pch=3,lty=3,col="darkblue",lwd=2.5,cex=1.2)
mtext("Price", side=2, at=40,line=2.5,cex=1.1)
axis(1, 1:10, cex.axis = 1.4)

die Handlung

Ich sollte beachten, dass ich mir wirklich keine Mühe gegeben habe, dies so schön wie möglich zu gestalten, und statt dieses ersten Dummy-Diagramms hätte ich im ersten Frame einfach genug Platz einstellen können. Leider versucht die Einstellung mar (), den Rahmen auszufüllen, und der obere Rand beeinflusst den Abstand, den die Beschriftung über dem Diagramm aufweist, sodass ich alle meine Beschriftungen mit mtext () oder text () erstellen muss, anstatt nur zu verwenden die Haupteinstellung in der Handlung und ich hatte keine Lust, das zu tun

John
quelle
zweitens die +1 für badass Basisgrafiken. Ich habe vergeblich versucht, mit dem Befehl layout () etwas Schönes zu schreiben. Ich werde das nächste Mal hierher zurückkehren, wenn ich es benutzen muss.
Chris Beeley
13

Ich würde empfehlen, das Gittergrafikpaket zu lernen. Mit ein paar Zeilen komme ich dem nahe, was Sie wollen. Packen Sie zunächst Ihre Daten in einen Datenrahmen, etwa so:

dat <- data.frame (x=rep (1:10, 8), y=c(a1, a2, b1, b2, c1, c2, d1, d2),
        var=factor (rep (c("X", "Y"), each=10)),
        graph=factor (rep (c("A", "B", "C", "D"), each=20)))

was ergibt:

    x           y var graph
1   1 0.556372979   X     A
2   2 0.754257646   X     A
3   3 0.815432905   X     A
4   4 0.559513013   X     A
5   5 0.763368168   X     A
6   6 0.426415259   X     A
7   7 0.597962532   X     A
8   8 0.723780143   X     A
9   9 0.228920116   X     A
10 10 0.607378894   X     A
11  1 0.865114425   Y     A
12  2 0.919804947   Y     A
13  3 0.437003794   Y     A
14  4 0.203349303   Y     A
15  5 0.620425977   Y     A
16  6 0.703170299   Y     A
17  7 0.174297656   Y     A
18  8 0.698144659   Y     A
19  9 0.732527016   Y     A
20 10 0.778057398   Y     A
21  1 0.355583032   X     B
22  2 0.015765144   X     B
23  3 0.315004753   X     B
24  4 0.257723585   X     B
25  5 0.506324279   X     B
26  6 0.028634427   X     B
27  7 0.475360443   X     B
28  8 0.577119754   X     B
29  9 0.709063777   X     B
30 10 0.308695235   X     B
31  1 0.852567748   Y     B
32  2 0.938889121   Y     B
33  3 0.080869739   Y     B
34  4 0.732318482   Y     B
35  5 0.325673156   Y     B
36  6 0.378161864   Y     B
37  7 0.830962248   Y     B
38  8 0.990504039   Y     B
39  9 0.331377188   Y     B
40 10 0.448251682   Y     B
41  1 0.967255983   X     C
42  2 0.722894624   X     C
43  3 0.039523960   X     C
44  4 0.003774719   X     C
45  5 0.218605160   X     C
46  6 0.722304874   X     C
47  7 0.576140686   X     C
48  8 0.108219812   X     C
49  9 0.258440127   X     C
50 10 0.739656846   X     C
51  1 0.528278201   Y     C
52  2 0.104415716   Y     C
53  3 0.966076056   Y     C
54  4 0.504415150   Y     C
55  5 0.655384900   Y     C
56  6 0.247340395   Y     C
57  7 0.193857228   Y     C
58  8 0.019133583   Y     C
59  9 0.799404908   Y     C
60 10 0.159209090   Y     C
61  1 0.422574508   X     D
62  2 0.823192614   X     D
63  3 0.808715876   X     D
64  4 0.770499188   X     D
65  5 0.049138399   X     D
66  6 0.747017767   X     D
67  7 0.239916970   X     D
68  8 0.152777362   X     D
69  9 0.052862276   X     D
70 10 0.937605577   X     D
71  1 0.850112019   Y     D
72  2 0.675407232   Y     D
73  3 0.273276166   Y     D
74  4 0.455995477   Y     D
75  5 0.695497498   Y     D
76  6 0.688414035   Y     D
77  7 0.454013633   Y     D
78  8 0.874853452   Y     D
79  9 0.568746031   Y     D

Dann benutze Gitter xyplot:

library (lattice)
xyplot (y ~ x | graph, groups=var, data=dat, type="o",
        layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price")

Das ergibt eine schöne Grafik wie:

Bildbeschreibung hier eingeben

BEARBEITEN:

Wenn Sie verschiedene Symbole und Linien haben möchten und diese in Ihrer Legende angezeigt werden sollen, wird dies kompliziert, da Sie die Legende buchstäblich selbst erstellen und wissen müssen, wie Sie die Standardgitterfarben erhalten, wenn Sie sie nicht selbst überschrieben haben :

my.text <- levels (dat$var)
my.lty <- c(2, 3)
my.pch <- c(1, 2)
my.col <- trellis.par.get ("superpose.symbol")$col[1:2]
xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=my.pch, lty=my.lty,
        main="Main Title", layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price",
        key=list (columns=2, text=list (my.text), points=list (pch=my.pch, col=my.col)))

Bildbeschreibung hier eingeben

EDIT 2:

Sie können den Code und das Diagramm vereinfachen, wenn die beiden Kategorien wirklich so einfach wie "X" und "Y" sind:

xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=c("X", "Y"), cex=1.25, lty=c(2, 3),
        layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price")

Hier werden "X" und "Y" als Punktsymbole verwendet. Sie brauchen überhaupt keine Legende und können dann den Diagrammen selbst noch mehr Platz widmen. (Auf der anderen Seite gefällt Ihnen das Aussehen möglicherweise nicht oder es fällt Ihnen schwerer, den genauen Mittelpunkt des Punkts zu bestimmen, obwohl dies möglicherweise kein so großes Problem darstellt, da die Linie durch jeden Punkt verläuft.)

EDIT 3:

Tatsächlich sollten Sie strip=F, strip.left=T,dem Plot die Bezeichnungen A, B, C, D links von den Diagrammen hinzufügen , um mehr Platz für ein langes Diagramm wie dieses zu haben:

xyplot (y ~ x | graph, groups=var, data=dat, type="o", pch=my.pch, lty=my.lty,
        main="Main Title", layout=c(1, 4), as.table=T, xlab="Time (secs)", ylab="Price",
        strip.left=T, strip=F,
        key=list (columns=2, text=list (my.text), points=list (pch=my.pch, col=my.col),
        lines=list (lty=my.lty, col=my.col)))

Bildbeschreibung hier eingeben

Wayne
quelle
@ Wayne: Ich versuche, eine Legende mit auto.key mit den Argumenten space = "top", pch = c (1,2), lty = c (2,4), aber den pch-Werten und über dem Diagramm zu belassen Lty-Werte funktionieren nicht. Außerdem möchte ich das X und Y in der Legende horizontal halten. Könnten Sie mir bitte dabei helfen?
Samarasa
Ja. Ich muss verschiedene pch-Werte verwenden, um X und Y auf einem Papier zu unterscheiden. Ich kann verschiedene pch-Werte im Plot verwenden, indem ich das Argument pch (1,4) zu xyplot hinzufüge, aber es spiegelt nicht die Legende wider. Bitte lassen Sie mich wissen, wie ich in der Legende unterschiedliche pch-Werte für X und Y verwenden kann.
Samarasa
OK, ich habe es herausgefunden, als ich nach Hause kam und das Buch konsultierte. Überprüfen Sie die bearbeitete Version.
Wayne
Kein Problem. Ich denke, mein EDIT 3 bietet Ihnen das beste Diagramm, das Ihrem Original ähnelt (aber besser aussieht und mehr Grafikfläche bietet als dieses). Ich habe die Legende nicht verschoben, was meiner Meinung nach ziemlich einfach ist. Wenn Sie möchten, dass die Linie den Punkt in der Legende durchläuft, müssten Sie sie auf die nächste Komplexitätsstufe bringen und die wichtigsten Aufgaben ausführen, mit denen benutzerdefinierte Grobs erstellt werden (eine gridSache: Gitter und ggplot2 bauen auf Gitter auf). .
Wayne
Ja, jetzt ist die Grafik besser. Es wäre jedoch sehr gut, wenn wir den Punkt über die Linie in der Legende bringen würden, wie wir es mit der normalen Plotfunktion tun würden.
Samarasa
9

Hier ist eine Version von @ Brandons ggplot2Lösung, die das gewünschte Legendenverhalten enthält:

dat <- data.frame (x=rep (1:10, 8), y=runif(80),
        var=factor (rep (c("X", "Y"), each=10)),
        graph=factor (rep (c("A", "B", "C", "D"), each=20)))

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, group = var)) + 
    labs(x = NULL, y = NULL, shape = "", colour = "") + 
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal")

Bildbeschreibung hier eingeben

Ich finde Legenden viel einfacher ggplot2, aber YMMV.

BEARBEITEN

Ein paar Fragen in den Kommentaren ansprechen. Um bestimmte Punkt- oder Linientypen anzugeben, verwenden Sie entweder , scale_aesthetic_manualwo usw. Zum Beispiel:aestheticshapelinetype

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, linetype = var, group = var)) + 
    labs(x = NULL, y = NULL, shape = "", colour = "", linetype = "") + 
    scale_shape_manual(values = 4:5) +
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal")

Das Ändern der Größe verschiedener Achsenbeschriftungen erfolgt durch Ändern der Einstellungen im Thema, in der Regel mit opts(). Zum Beispiel:

ggplot(data = dat,aes(x = x, y = y)) + 
    facet_wrap(~graph,nrow = 4) + 
    geom_point(aes(shape = var)) + 
    geom_line(aes(colour = var, linetype = var, group = var)) + 
    labs(x = "X Label", y = "Y Label", shape = "", colour = "", linetype = "") + 
    theme_bw() + 
    opts(legend.position = "top", legend.direction = "horizontal",
         axis.text.x = theme_text(size = 15),axis.title.y = theme_text(size = 25, angle = 90))

Sie sollten wirklich in die Website und sein Buch eintauchen, um weitere Informationen zu erhalten.

joran
quelle
2
Ich bevorzuge oft ggplot2. Tatsächlich habe ich einen kurzen Versuch mit ggplot2 gemacht, als das Gitter zu komplex wurde, und festgestellt, dass ich die Legende nicht richtig wiedergeben konnte, wenn ich explizit Formen und Linienstile auswählen wollte. Wahrscheinlich habe ich es falsch gemacht und es gelang mir, im Diagramm zu arbeiten, aber ich habe die Legendenerstellung von ggplot getäuscht. Könnten Sie sehen, ob es für Sie funktioniert, und den Code posten?
Wayne
@Joran: Ich habe versucht herauszufinden, ob die Linientypen und Punkttypen sowie die Farben geändert werden sollen, aber kein Erfolg. Können Sie uns mitteilen, wie wir die Linientypen usw. ändern können? Lassen Sie uns auch wissen, wie wir die Größe von x- und y-Labors erhöhen können.
Samarasa
Ich bin gerade auf meinem Handy. Wenn @Brandon seine Antwort nicht bearbeitet, bevor ich mit dem, was Sie suchen, nach Hause komme, werde ich es später heute Abend tun.
Joran
8

Ähnlich wie bei Waynes Antwort würde ich auch ein anderes Paket verwenden, nämlich ggplot2

library(ggplot2) 

df <- data.frame(
parameter=runif(300),
Time=1:300,
split=sample(c(1:4),300,replace=T),
split2=sample(c(1:2),300,replace=T)
)

ggplot(df, aes(Time, parameter, colour=as.factor(split2))) + 
geom_line() + 
facet_wrap(~split,nrow=4)

Was uns ein Diagramm gibt wie:

Bildbeschreibung hier eingeben

Brandon Bertelsen
quelle
1
Ich mag die Gitter in ggplot, aber gibt es eine Möglichkeit, den hellgrauen Hintergrund auszuschalten?
Bluepole
1
+ opts(panel.background=theme_blank())
Brandon Bertelsen
1
Wenn Sie andere Änderungen vornehmen möchten, können Sie eingeben, um theme_get()zu sehen, was Sie ändern können. Folgen Sie dann dem gleichen Muster wie bei meinem letzten Kommentar und stellen Sie sie ein=theme_blank()
Brandon Bertelsen,
2
Ich wollte ggplot2 selbst machen, dachte aber, Gitter wäre vielleicht ein einfacherer Schritt. Beide bieten eine strukturierte Möglichkeit zum Stapeln von Diagrammen. Viele Details zu optimieren kann schwierig werden, aber es ist einfach, schnell etwas Attraktives und Lesbares zu finden. (Allerdings müssen Sie den Kopf darum legen, den richtigen Datenrahmen für die grafische Darstellung der Daten zu erstellen, anstatt nur Daten in die Grafik zu werfen.
Wayne,
Ich habe festgestellt, dass Hadley in seinen anderen Paketen Datenbearbeitungswerkzeuge zur Verfügung gestellt hat, um die Daten in die richtige Form zu bringen. Im Zweifelsfall lautet die Antwort in der Regelmelt()
Brandon Bertelsen