Dessinez plusieurs tracés sur un graphique dans R?

13

En utilisant le code suivant, j'ai essayé de dessiner quatre graphiques sur un graphique R. Je ne suis pas satisfait du chiffre car il y a beaucoup d'espace entre les parcelles, donc la largeur des parcelles n'est pas suffisante pour analyser les parcelles.

  1. Quelqu'un pourrait-il m'aider à produire un joli graphique comportant quatre tracés?

  2. Comment puis-je conserver les étiquettes de l'axe des x de 1 à 10 au lieu des 5 étiquettes par défaut?

Les données:

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

J'ai utilisé les données a1 pour b1, c1 et d1; données a2 pour b2, c2 et d2 juste pour ici.

Figure:

entrez la description de l'image ici

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
la source
1
pourriez-vous pls donner les détails de vos données? éventuellement, dput (data_from_r)
suncoolsu
@suncoolsu, j'ai mis à jour la question avec un échantillon de données. Je vous remercie.
samarasa
Et si vous aviez 2 couleurs et 4 types de lignes sur les mêmes axes avec une légende? Je voudrais voir le code et les résultats pour cela.
Paul
@ user87: Puisque 4 parcelles proviennent de 4 expériences différentes. Par conséquent, je pense qu'il vaut mieux tracer 4 graphiques pour analyser les résultats des expériences.
samarasa
@ user87, je ne sais pas ce que vous voulez dire. Peut-être que si vous commenciez une nouvelle question, quelqu'un y répondrait (je le ferais :))
Brandon Bertelsen

Réponses:

16

Si vous voulez vous en tenir à quelque chose comme la méthode que vous avez utilisée, vous voudrez peut-être apprendre la commande layout (). Quelques autres changements de détails et vous pouvez rapprocher les graphiques. Vous pouvez également mettre les éléments uniques qui changent entre les graphiques dans une liste (comme les données et les marges), puis parcourir une boucle. De plus, vous remarquerez que j'ai créé l'axe inférieur avec la commande direct axis () afin que vous puissiez contrôler où vont les éléments.

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)

la parcelle

Je devrais noter que je n'ai vraiment pas fait d'effort pour rendre cela aussi agréable que possible et au lieu de faire ce premier graphique factice, j'aurais pu juste mettre assez d'espace dans la première image. Malheureusement, le paramètre mar () essaie de remplir le cadre et la marge supérieure influence la distance à laquelle l'étiquette au-dessus du graphique est éloignée, je devrais donc faire toutes mes étiquettes avec mtext () ou text () au lieu d'utiliser simplement le paramètre principal dans l'intrigue et je n'avais pas envie de faire ça

John
la source
seconde le +1 pour les graphiques de base badass. J'ai essayé en vain d'écrire quelque chose de sympa avec la commande layout (). Je vais revenir ici la prochaine fois que je devrai l'utiliser.
Chris Beeley
13

Je recommanderais d'apprendre le package graphique en treillis. Je peux me rapprocher de ce que vous voulez en quelques lignes. Tout d'abord, regroupez vos données dans un bloc de données, quelque chose comme ceci:

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)))

ce qui donne:

    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

Ensuite, utilisez le treillis 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")

ce qui donne un joli graphique comme:

entrez la description de l'image ici

ÉDITER:

Si vous voulez avoir différents symboles et lignes et que cela apparaisse dans votre légende, cela se complique, car vous créez littéralement la légende vous-même, et vous devez savoir comment obtenir les couleurs de réseau par défaut si vous ne les avez pas remplacées vous-même :

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)))

entrez la description de l'image ici

EDIT 2:

Vous pouvez simplifier le code et le graphique, si les deux catégories sont vraiment aussi simples que "X" et "Y":

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")

qui utilisera "X" et "Y" comme symboles ponctuels. Vous n'avez pas du tout besoin d'une légende et pouvez alors consacrer encore plus d'espace aux graphiques eux-mêmes. (D'un autre côté, vous pourriez ne pas aimer l'apparence ou trouver plus difficile de déterminer le centre exact du point, bien que ce ne soit pas autant un problème que cela pourrait être puisque la ligne passe par chaque point.)

EDIT 3:

En fait, vous devriez ajouter strip=F, strip.left=T,à l'intrigue, pour placer les étiquettes A, B, C, D à gauche des graphiques, ce qui vous donne plus d'espace sur un long graphique comme celui-ci:

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)))

entrez la description de l'image ici

Wayne
la source
@Wayne: J'essaie de garder une légende en haut du graphique en utilisant auto.key avec space = "top", pch = c (1,2), lty = c (2,4) arguments, mais les valeurs pch et Les valeurs ne fonctionnent pas. De plus, je voudrais garder les X et Y horizontaux dans la légende. Pourriez-vous s'il vous plaît m'aider pour cela.
samarasa
Oui. J'ai besoin d'utiliser différentes valeurs de pch pour distinguer X et Y sur un papier. Je peux utiliser différentes valeurs de pch dans l'intrigue en ajoutant l'argument pch (1,4) à xyplot, mais cela ne reflète pas la légende. Veuillez me faire savoir comment puis-je utiliser différentes valeurs de pch pour X et Y dans la légende.
samarasa
OK, je l'ai compris une fois à la maison et j'ai consulté le livre. Découvrez la version éditée.
Wayne
Aucun problème. Je pense que mon EDIT 3 vous donne le meilleur graphique similaire (mais plus beau et avec plus d'espace graphique que) votre original. Je n'ai pas déplacé la légende, qui je pense est assez simple. Si vous voulez que la ligne passe par le point de la légende, je pense que vous devriez le prendre au niveau de complexité suivant et faire des trucs draw.key qui créent des grobs personnalisés (une gridchose: treillis et ggplot2 construits sur la grille) .
Wayne
Oui, maintenant le graphique est meilleur. Cependant, ce serait vraiment bien si nous obtenons le point sur la ligne dans la légende comme nous obtenons avec la fonction de tracé normale.
samarasa
9

Voici une version de la ggplot2solution de @ Brandon qui incorpore le comportement de légende souhaité:

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")

entrez la description de l'image ici

Je trouve que les légendes sont beaucoup plus faciles ggplot2, mais YMMV.

ÉDITER

Répondre à quelques questions dans les commentaires. Pour définir le point ou de certains types ligne, vous utilisez scale_aesthetic_manualaestheticest soit shape, linetypeetc. Par exemple:

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")

La modification de la taille des différentes étiquettes d'axe se fait en modifiant les paramètres du thème, généralement à l'aide de opts(). Par exemple:

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))

Vous devriez vraiment plonger dans le site Web et son livre pour plus d'informations.

joran
la source
2
Je préfère souvent ggplot2. En fait, j'ai fait un essai rapide avec ggplot2 lorsque le réseau devenait trop complexe, et j'ai constaté que je ne pouvais pas tout à fait obtenir la légende pour refléter correctement les styles de point / ligne si je voulais choisir explicitement les formes et les styles de ligne. Je l'ai probablement fait dans le mauvais sens, et il a réussi à fonctionner dans le graphique, mais a trompé la création de la légende de ggplot. Pourriez-vous voir si cela fonctionne pour vous et publier le code?
Wayne
@Joran: J'ai essayé de comprendre pour changer les types de ligne et les types de point, et les couleurs, mais sans succès. Pourriez-vous nous faire savoir comment pouvons-nous changer les types de ligne, etc.
samarasa
Je suis en ce moment sur mon téléphone; si @Brandon ne modifie pas sa réponse avant de rentrer à la maison avec ce que vous cherchez, j'y reviendrai plus tard ce soir.
joran
8

Semblable à la réponse de Wayne, j'utiliserais également un package différent, à savoir 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)

Ce qui nous donne un graphique comme:

entrez la description de l'image ici

Brandon Bertelsen
la source
1
J'aime les grilles dans ggplot, mais existe-t-il un moyen de désactiver le fond gris clair?
poteau bleu
1
+ opts(panel.background=theme_blank())
Brandon Bertelsen
1
Si vous souhaitez apporter d'autres modifications, vous pouvez taper theme_get()pour voir ce que vous pouvez modifier. Ensuite, suivez le même modèle que mon dernier commentaire, en les définissant=theme_blank()
Brandon Bertelsen
2
J'allais faire ggplot2 moi-même, mais je pensais que le réseau serait peut-être une étape plus facile. L'un ou l'autre fournit un moyen structuré d'empiler des graphiques comme celui-ci. Il peut être difficile de modifier de nombreux détails, mais il est facile d'obtenir quelque chose d'attrayant et de lisible rapidement. (Bien que vous deviez vous concentrer sur la création du cadre de données approprié à partir duquel représenter graphiquement les données, au lieu de simplement jeter des éléments dans le graphique.
Wayne
J'ai trouvé que Hadley a fourni des outils de manipulation de données dans ses autres packages pour masser les données dans la bonne forme. En cas de doute, la réponse est généralement,melt()
Brandon Bertelsen