Tracer deux graphiques dans le même tracé en R


572

Je voudrais tracer y1 et y2 dans le même tracé.

x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)
plot(x, y1, type = "l", col = "red")
plot(x, y2, type = "l", col = "green")

Mais quand je le fais comme ça, ils ne sont pas tracés ensemble dans le même tracé.

Dans Matlab, on peut le faire hold on, mais quelqu'un sait-il comment faire cela dans R?


3
Découvrez ?curve. Utilisez add=TRUE.
isomorphismes

Voir cette question pour des réponses plus spécifiques à ggplot2.
Axeman

Réponses:


618

lines()ou points()s'ajoutera au graphique existant, mais ne créera pas de nouvelle fenêtre. Vous devez donc faire

plot(x,y1,type="l",col="red")
lines(x,y2,col="green")

10
Pourquoi cela ne fonctionne-t-il pas dans l'exemple simple suivant? > plot (sin)> lines (cos) Erreur dans as.double (y): impossible de contraindre le type 'builtin' au vecteur de type 'double'
Frank

23
C'est facile à voir. Avec plot (sin), vous passez une fonction au lieu de données réelles. plot () détectera cela et utilisera à son tour plot.function () pour tracer votre fonction (lisez les répartitions multiples pour en savoir plus). Cependant, lines.function () n'est pas défini, donc lines () ne sait pas quoi faire avec un paramètre de fonction de classe. les lignes ne peuvent traiter que vos données et objets de séries chronologiques de classe ts.
Soumendra

27
@Frank le faire comme ceci: plot(sin); curve(cos, add=TRUE).
isomorphismes

2
Comment utiliser le même si x est différent? Disons que j'ai x1 et y1 pour un graphique et ajoute un autre graphique de x2 et y2 dans le même graphique. Les deux x1 et x2 ont la même plage mais des valeurs différentes.
Kavipriya

1
C'est exactement la même chose: lines(x2,y2,...)au lieu delines(x,y2,...)
bnaul

220

Vous pouvez également utiliser paret tracer sur le même graphique mais sur un axe différent. Quelque chose comme suit:

plot( x, y1, type="l", col="red" )
par(new=TRUE)
plot( x, y2, type="l", col="green" )

Si vous lisez en détail pardans R, vous pourrez générer des graphiques vraiment intéressants. Un autre livre à regarder est R Graphics de Paul Murrel.


3
Mon R me donne une erreur: Erreur au par (fig (nouveau = TRUE)): impossible de trouver la fonction "fig"
Alessandro Jacopson

5
Votre méthode préserve-t-elle la bonne échelle (axe y) pour les deux tracés?
Alessandro Jacopson

1
@uvts_cvs Oui, il conserve le graphique d'origine dans son intégralité.
Sam

10
Le problème est qu'il réécrira plusieurs éléments de tracé. Je voudrais inclure xlab="", ylab="", ...et quelques autres dans le second plot.
isomorphismes

118

Lors de la construction de tracés multicouches, il faut tenir compte ggplot package. L'idée est de créer un objet graphique avec une esthétique de base et de l'améliorer progressivement.

ggplotle style nécessite que les données soient regroupées data.frame.

# Data generation
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
df <- data.frame(x,y1,y2)

Solution basique:

require(ggplot2)

ggplot(df, aes(x)) +                    # basic graphical object
  geom_line(aes(y=y1), colour="red") +  # first layer
  geom_line(aes(y=y2), colour="green")  # second layer

Ici + operatorest utilisé pour ajouter des couches supplémentaires à l'objet de base.

Avec ggplotvous avez accès à un objet graphique à chaque étape du traçage. Disons, la configuration étape par étape habituelle peut ressembler à ceci:

g <- ggplot(df, aes(x))
g <- g + geom_line(aes(y=y1), colour="red")
g <- g + geom_line(aes(y=y2), colour="green")
g

gproduit l'intrigue, et vous pouvez le voir à chaque étape (enfin, après la création d'au moins une couche). D'autres enchantements de l'intrigue sont également réalisés avec l'objet créé. Par exemple, nous pouvons ajouter des étiquettes pour les axes:

g <- g + ylab("Y") + xlab("X")
g

La finale gressemble à:

entrez la description de l'image ici

MISE À JOUR (2013-11-08):

Comme indiqué dans les commentaires, ggplotla philosophie de suggère d'utiliser des données au format long. Vous pouvez vous référer à cette réponse pour voir le code correspondant.


5
Comme suggéré par Henrik , les données devraient vraiment être au format "long", ggplotcela le gère plus naturellement que le format "large" que vous utilisez.
krlmlr

1
@Henrik: Non, merci pour votre réponse en premier lieu. Peut-être que l'auteur de cette réponse peut la modifier pour qu'elle corresponde bien à ggplotla philosophie de ...
krlmlr

1
@krlmlr, j'ai essayé de modifier ma réponse afin qu'elle réponde plus explicitement à la question. N'hésitez pas à suggérer d'autres mises à jour. À votre santé.
Henrik

3
m'a appris à définir x sur ggplot (aes ()) puis y par lui-même sur geom _ * (). Agréable!
Dan

41

Je pense que la réponse que vous cherchez est:

plot(first thing to plot)
plot(second thing to plot,add=TRUE)

25
Cela ne semble pas fonctionner, il donne un "add" is not a graphical parameteravertissement puis imprime simplement le deuxième tracé sur le premier.
Waldir Leoncio


Un bon avantage de ceci est qu'il semble garder les limites des axes et les titres cohérents. Certaines des méthodes précédentes obligent R à dessiner deux ensembles de graduations sur l'axe des y, sauf si vous rencontrez des difficultés pour spécifier plus d'options. Inutile de dire que le fait d'avoir deux séries de graduations sur les axes peut être très trompeur.
RMurphy

1
le paramètre add fonctionne pour certaines méthodes de tracé, mais pas celui de base / par défaut dans R
cloudscomputes

2
J'ai la même erreur "add" is not a graphical parameter. Mon R est R version 3.2.3 (2015-12-10). Vous pouvez utiliser la par(new=TRUE)commande entre ces tracés.
quepas

29

Utilisez la matplotfonction:

matplot(x, cbind(y1,y2),type="l",col=c("red","green"),lty=c(1,1))

utilisez-le si y1et y2sont évalués aux mêmes xpoints. Il met à l'échelle l'axe Y pour s'adapter à ce qui est le plus grand ( y1ou y2), contrairement à certaines des autres réponses ici qui se couperont y2si elle devient plus grande quey1 écrêtées (les solutions ggplot sont généralement d'accord avec cela).

Alternativement, et si les deux lignes n'ont pas les mêmes coordonnées x, définissez les limites de l'axe sur le premier tracé et ajoutez:

x1  <- seq(-2, 2, 0.05)
x2  <- seq(-3, 3, 0.05)
y1 <- pnorm(x1)
y2 <- pnorm(x2,1,1)

plot(x1,y1,ylim=range(c(y1,y2)),xlim=range(c(x1,x2)), type="l",col="red")
lines(x2,y2,col="green")

Je suis étonné que ce Q ait 4 ans et que personne n'ait mentionné matplotou x/ylim...


25

tl; dr: vous souhaitez utiliser curve(avec add=TRUE) ou lines.


Je ne suis pas d'accord, par(new=TRUE)car cela double l'impression des graduations et des étiquettes d'axe. Par exemple

sinus et parabole

La sortie de plot(sin); par(new=T); plot( function(x) x**2 ).

Regardez à quel point les étiquettes des axes verticaux sont en désordre! Étant donné que les plages sont différentes, vous devez définir ylim=c(lowest point between the two functions, highest point between the two functions), ce qui est moins facile que ce que je vais vous montrer --- et beaucoup moins facile si vous voulez ajouter non seulement deux courbes, mais plusieurs.


Ce qui m'a toujours dérouté dans le complot, c'est la différence entre curveet lines. (Si vous ne vous souvenez pas que ce sont les noms des deux commandes de traçage importantes, chantez simplement -les.)

Voici la grande différence entre curveetlines .

curvetracera une fonction, comme curve(sin). linestrace des points avec des valeurs x et y, comme:lines( x=0:10, y=sin(0:10) ) .

Et voici une différence mineure: curvedoit être appelé add=TRUEpour ce que vous essayez de faire, tout en linessupposant déjà que vous ajoutez à un tracé existant.

id & sine

Voici le résultat de l'appel plot(0:2); curve(sin).


Dans les coulisses, consultez methods(plot). Et vérifiez body( plot.function )[[5]]. Lorsque vous appelez plot(sin)R, il sins'agit d'une fonction (et non de valeurs y) et utilise la plot.functionméthode, qui finit par appeler curve. Il en curveva de même de l'outil destiné à gérer les fonctions.


17

si vous voulez diviser le tracé en deux colonnes (2 tracés côte à côte), vous pouvez le faire comme ceci:

par(mfrow=c(1,2))

plot(x)

plot(y) 

Lien de référence


16

Comme décrit par @redmode, vous pouvez tracer les deux lignes dans le même périphérique graphique en utilisant ggplot. Dans cette réponse, les données étaient dans un format «large». Cependant, lors de l'utilisation, ggplotil est généralement plus pratique de conserver les données dans une trame de données dans un format «long». Ensuite, en utilisant différentes «variables de regroupement» dans leaes arguments thétiques, les propriétés de la ligne, telles que le type de ligne ou la couleur, varieront en fonction de la variable de regroupement et les légendes correspondantes apparaîtront.

Dans ce cas, nous pouvons utiliser l' colouresthétique, qui fait correspondre la couleur des lignes aux différents niveaux d'une variable dans l'ensemble de données (ici: y1 vs y2). Mais nous devons d'abord faire fondre les données du format large au format long, en utilisant par exemple la fonction «fondre» du reshape2package. D'autres méthodes pour remodeler les données sont décrites ici: Remodelage de data.frame du format large au format long .

library(ggplot2)
library(reshape2)

# original data in a 'wide' format
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)
df <- data.frame(x, y1, y2)

# melt the data to a long format
df2 <- melt(data = df, id.vars = "x")

# plot, using the aesthetics argument 'colour'
ggplot(data = df2, aes(x = x, y = value, colour = variable)) + geom_line()

entrez la description de l'image ici


15

Si vous utilisez des graphiques de base (c'est-à-dire pas des graphiques en treillis / grille), vous pouvez imiter la fonction de maintien de MATLAB en utilisant les fonctions points / lignes / polygones pour ajouter des détails supplémentaires à vos tracés sans démarrer un nouveau tracé. Dans le cas d'une disposition multiplot, vous pouvez utiliser par(mfg=...)pour choisir le tracé auquel vous ajoutez des éléments.


14

Vous pouvez utiliser des points pour la superposition, c'est-à-dire.

plot(x1, y1,col='red')

points(x2,y2,col='blue')

7

Plutôt que de conserver les valeurs à tracer dans un tableau, stockez-les dans une matrice. Par défaut, la matrice entière sera traitée comme un seul ensemble de données. Cependant, si vous ajoutez le même nombre de modificateurs au tracé, par exemple col (), que vous avez des lignes dans la matrice, R déterminera que chaque ligne doit être traitée indépendamment. Par exemple:

x = matrix( c(21,50,80,41), nrow=2 )
y = matrix( c(1,2,1,2), nrow=2 )
plot(x, y, col("red","blue")

Cela devrait fonctionner à moins que vos ensembles de données soient de tailles différentes.


Cela donne: Erreur dans if (as.factor) {: l'argument n'est pas interprétable comme logique
baouss


5

Vous pouvez utiliser la ggplotly()fonction du package plotly pour transformer l'un des exemples de gggplot2 ici en un tracé interactif, mais je pense que ce type de tracé est meilleur sans ggplot2 :

# call Plotly and enter username and key
library(plotly)
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)

plot_ly(x = x) %>%
  add_lines(y = y1, color = I("red"), name = "Red") %>%
  add_lines(y = y2, color = I("green"), name = "Green")

entrez la description de l'image ici


semble incroyablement brillant; c'est gratuit ?
denis

@denis, il y a un traçage public gratuit illimité et des options de traçage privé payant ou sur site. Voir la page des plans .
Mateo Sanchez

4
Le package complot R est maintenant 100% gratuit et open source (sous licence MIT). Vous pouvez l'utiliser avec ou sans compte complot.
Carson

4

Vous pouvez également créer votre tracé à l'aide de ggvis :

library(ggvis)

x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
df <- data.frame(x, y1, y2)

df %>%
  ggvis(~x, ~y1, stroke := 'red') %>%
  layer_paths() %>%
  layer_paths(data = df, x = ~x, y = ~y2, stroke := 'blue')

Cela créera le tracé suivant:

entrez la description de l'image ici


2

Utilisation plotly(ajout de solution à partir plotlydes axes y primaire et secondaire - Il semble manquer):

library(plotly)     
x  <- seq(-2, 2, 0.05)
y1 <- pnorm(x)
y2 <- pnorm(x, 1, 1)

df=cbind.data.frame(x,y1,y2)

  plot_ly(df) %>%
    add_trace(x=~x,y=~y1,name = 'Line 1',type = 'scatter',mode = 'lines+markers',connectgaps = TRUE) %>%
    add_trace(x=~x,y=~y2,name = 'Line 2',type = 'scatter',mode = 'lines+markers',connectgaps = TRUE,yaxis = "y2") %>%
    layout(title = 'Title',
       xaxis = list(title = "X-axis title"),
       yaxis2 = list(side = 'right', overlaying = "y", title = 'secondary y axis', showgrid = FALSE, zeroline = FALSE))

Capture d'écran de la démonstration de travail:

entrez la description de l'image ici


J'ai compilé le code et ne fonctionne pas, j'ai d'abord marqué une erreur dans%>% et je l'ai supprimé, puis j'ai marqué une erreur Error in library(plotly) : there is no package called ‘plotly’pourquoi?
Bellatrix

Avez-vous installé le package plotly? Vous devez installer le package à l'aide de la install.packages("plotly")commande.
Saurabh Chauhan

1

nous pouvons également utiliser la bibliothèque de treillis

library(lattice)
x <- seq(-2,2,0.05)
y1 <- pnorm(x)
y2 <- pnorm(x,1,1)
xyplot(y1 + y2 ~ x, ylab = "y1 and y2", type = "l", auto.key = list(points = FALSE,lines = TRUE))

Pour des couleurs spécifiques

xyplot(y1 + y2 ~ x,ylab = "y1 and y2", type = "l", auto.key = list(points = F,lines = T), par.settings = list(superpose.line = list(col = c("red","green"))))

entrez la description de l'image ici

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.