Traccia due grafici nella stessa trama in R


571

Vorrei tracciare y1 e y2 nella stessa trama.

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

Ma quando lo faccio in questo modo, non vengono tracciati insieme nella stessa trama.

In Matlab si può fare hold on, ma qualcuno sa come farlo in R?


3
Partenza ?curve. Usa add=TRUE.
isomorfismi

Vedi questa domanda per risposte ggplot2 più specifiche.
Axeman,

Risposte:


617

lines()o points()aggiungerà al grafico esistente, ma non creerà una nuova finestra. Quindi dovresti farlo

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

10
Perché non funziona nel seguente semplice esempio? > plot (sin)> lines (cos) Errore in as.double (y): impossibile forzare il tipo 'builtin' nel vettore di tipo 'double'
Frank

23
Questo è facile da vedere. Con plot (sin), si passa una funzione anziché i dati effettivi. plot () rileverà questo e, a sua volta, utilizzerà plot.function () per tracciare la tua funzione (leggi su più invii per saperne di più su questo). Tuttavia, lines.function () non è definito, quindi lines () non sa cosa fare con un parametro della funzione class. le righe possono gestire solo i tuoi dati e oggetti della serie temporale della classe ts.
Soumendra,

27
@Frank fare in questo modo: plot(sin); curve(cos, add=TRUE).
isomorfismi

2
Come usare lo stesso se x è diverso? Dì, ho x1 e y1 per un grafico e aggiungo un altro grafico di x2 e y2 nello stesso grafico. Sia x1 che x2 hanno lo stesso intervallo ma valori diversi.
Kavipriya,

1
È esattamente lo stesso: lines(x2,y2,...)invece dilines(x,y2,...)
bnaul

220

Puoi anche usare pare tracciare sullo stesso grafico ma assi diversi. Qualcosa come segue:

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

Se leggi in dettaglio su parin R, sarai in grado di generare grafici davvero interessanti. Un altro libro da guardare è la R Graphics di Paul Murrel.


3
La mia R mi dà un errore: Errore nel par (fig (nuovo = VERO)): impossibile trovare la funzione "fig"
Alessandro Jacopson,

5
Il tuo metodo mantiene la scala corretta (asse y) per i due grafici?
Alessandro Jacopson,

1
@uvts_cvs Sì, conserva il grafico originale in toto.
Sam,

10
Il problema è che riscriverà diversi elementi della trama. Vorrei includere xlab="", ylab="", ...e alcuni altri nel secondo plot.
isomorfismi

118

Quando si costruiscono grafici multistrato, è necessario considerare il ggplotpacchetto. L'idea è di creare un oggetto grafico con un'estetica di base e migliorarlo in modo incrementale.

ggplotlo stile richiede il confezionamento dei dati data.frame.

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

Soluzione di base:

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

Qui + operatorè usato per aggiungere livelli extra all'oggetto base.

Con ggplotte hai accesso all'oggetto grafico in ogni fase della stampa. Supponiamo che la normale configurazione dettagliata possa assomigliare a questa:

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

gproduce la trama e puoi vederla in ogni fase (beh, dopo la creazione di almeno un livello). Ulteriori incantesimi della trama sono fatti anche con l'oggetto creato. Ad esempio, possiamo aggiungere etichette per gli assi:

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

La finale gè simile a:

inserisci qui la descrizione dell'immagine

AGGIORNAMENTO (2013-11-08):

Come sottolineato nei commenti, ggplotla filosofia suggerisce di utilizzare i dati in formato lungo. Puoi fare riferimento a questa risposta per vedere il codice corrispondente.


5
Come suggerito da Henrik , i dati dovrebbero davvero essere in formato "lungo", lo ggplotgestisce in modo più naturale rispetto al formato "largo" che si utilizza.
krlmlr,

1
@Henrik: No, grazie per la risposta in primo luogo. Forse l'autore di questa risposta può modificarla in modo che si adatti bene alla ggplotfilosofia di ...
krlmlr

1
@krlmlr, ho provato a modificare la mia risposta in modo da rispondere in modo più esplicito alla domanda. Non esitate a suggerire ulteriori aggiornamenti. Saluti.
Henrik,

3
mi ha insegnato a definire x su ggplot (aes ()) e poi y da solo su geom _ * (). Bello!
Dan

41

Penso che la risposta che stai cercando sia:

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

25
Questo non sembra funzionare, dà un "add" is not a graphical parameteravvertimento, quindi stampa solo la seconda trama sopra la prima.
Waldir Leoncio,


Un bel vantaggio di questo è che sembra mantenere coerenti limiti e titoli degli assi. Alcuni dei metodi precedenti inducono R a disegnare due serie di segni di spunta sull'asse y, a meno che non si riesca a specificare più opzioni. Inutile dire che avere due serie di segni di spunta sugli assi potrebbe essere molto fuorviante.
RMurphy,

1
il parametro add funziona per alcuni metodi della trama, ma non quello base / predefinito in R
cloud calcola il

2
Ho avuto lo stesso errore "add" is not a graphical parameter. La mia R è R version 3.2.3 (2015-12-10). È possibile utilizzare il par(new=TRUE)comando tra questi grafici.
quepas,

29

Usa la matplotfunzione:

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

usare questo se y1e y2vengono valutati negli stessi xpunti. Ridimensiona l'asse Y per adattarlo a qualsiasi sia più grande ( y1o y2), a differenza di alcune delle altre risposte qui che verranno tagliate y2se diventa più grande di y1(le soluzioni ggplot per lo più vanno bene con questo).

In alternativa, e se le due linee non hanno le stesse coordinate x, impostare i limiti degli assi sul primo grafico e aggiungere:

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

Stupito che questa Q abbia 4 anni e nessuno ha menzionato matploto x/ylim...


25

tl; dr: vuoi usare curve(con add=TRUE) o lines.


Non sono d'accordo par(new=TRUE)perché ciò consentirà di stampare due segni di spunta e le etichette degli assi. Per esempio

seno e parabola

L'output di plot(sin); par(new=T); plot( function(x) x**2 ).

Guarda come sono incasinate le etichette degli assi verticali! Poiché le gamme sono diverse, dovresti impostarle ylim=c(lowest point between the two functions, highest point between the two functions), il che è meno facile di quello che sto per mostrarti --- e molto meno facile se vuoi aggiungere non solo due curve, ma molte.


Ciò che mi ha sempre confuso riguardo alla trama è la differenza tra curvee lines. (Se non è possibile ricordare che questi sono i nomi dei due importanti comandi plottaggio, basta cantare esso.)

Ecco la grande differenza tra curvee lines.

curvetraccia una funzione, come curve(sin). linespiazzole punti con valori di xey, come: lines( x=0:10, y=sin(0:10) ).

Ed ecco una differenza minore: curvedeve essere chiamato add=TRUEper quello che stai cercando di fare, mentre linesgià presume che stai aggiungendo a una trama esistente.

id & sine

Ecco il risultato della chiamata plot(0:2); curve(sin).


Dietro le quinte, dai un'occhiata methods(plot). E controlla body( plot.function )[[5]]. Quando chiami plot(sin)R capisci che sinè una funzione (non valori y) e usa il plot.functionmetodo, che finisce per chiamare curve. Quindi curvelo strumento è pensato per gestire le funzioni.


17

se vuoi dividere il diagramma in due colonne (2 diagrammi uno accanto all'altro), puoi farlo in questo modo:

par(mfrow=c(1,2))

plot(x)

plot(y) 

Link di riferimento


16

Come descritto da @redmode, è possibile tracciare le due linee nello stesso dispositivo grafico usando ggplot. In quella risposta i dati erano in un formato "ampio". Tuttavia, quando ggplotlo si utilizza è generalmente più conveniente mantenere i dati in un frame di dati in un formato "lungo". Quindi, usando diverse "variabili di raggruppamento" negli aesargomenti di thetics, le proprietà della linea, come il tipo di linea o il colore, varieranno in base alla variabile di raggruppamento e appariranno le legende corrispondenti.

In questo caso, possiamo usare l' colouraessetica, che abbina il colore delle linee ai diversi livelli di una variabile nel set di dati (qui: y1 vs y2). Ma prima dobbiamo fondere i dati dal formato largo a quello lungo, usando ad es. La funzione 'melt' dal reshape2pacchetto. Altri metodi per rimodellare i dati sono descritti qui: Rimodellare data.frame da formato largo a lungo .

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

inserisci qui la descrizione dell'immagine


15

Se stai usando la grafica di base (cioè non la grata / la griglia), puoi imitare la funzione di blocco di MATLAB usando le funzioni punti / linee / poligoni per aggiungere ulteriori dettagli ai tuoi grafici senza iniziare una nuova trama. Nel caso di un layout multiplot, è possibile utilizzare par(mfg=...)per scegliere a quale trama aggiungere elementi.


14

È possibile utilizzare i punti per l'overplot, ovvero.

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

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

7

Invece di mantenere i valori da tracciare in un array, archiviarli in una matrice. Per impostazione predefinita, l'intera matrice verrà trattata come un set di dati. Tuttavia, se aggiungi lo stesso numero di modificatori al grafico, ad esempio col (), poiché hai le righe nella matrice, R scoprirà che ogni riga deve essere trattata in modo indipendente. Per esempio:

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

Questo dovrebbe funzionare a meno che i tuoi set di dati non abbiano dimensioni diverse.


Questo dà: Errore in if (as.factor) {: argomento non interpretabile come logico
baouss


5

Potresti usare la ggplotly()funzione dal pacchetto plotly per trasformare uno qualsiasi degli esempi gggplot2 qui in un grafico interattivo, ma penso che questo tipo di trama sia migliore senza 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")

inserisci qui la descrizione dell'immagine


la trama appare brillante; è gratis ?
denis,

@denis, la stampa pubblica gratuita illimitata e la stampa privata a pagamento o le opzioni locali. Vedi la pagina dei piani .
Mateo Sanchez,

4
Il plastico pacchetto R ora è gratuito al 100% e open source (licenza MIT). Puoi usarlo con o senza un account intricato.
Carson

4

Puoi anche creare la tua trama usando 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')

Questo creerà il seguente diagramma:

inserisci qui la descrizione dell'immagine


2

Utilizzando plotly(aggiunta di soluzione plotlycon asse y primario e secondario- Sembra mancare):

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

Screenshot dalla demo funzionante:

inserisci qui la descrizione dell'immagine


Ho compilato il codice e non funziona, ho prima contrassegnato un errore in%>% e l'ho eliminato, quindi contrassegnato un errore Error in library(plotly) : there is no package called ‘plotly’perché?
Bellatrix,

Hai installato il pacchetto plotly? Devi installare il pacchetto usando il install.packages("plotly")comando.
Saurabh Chauhan,

1

possiamo anche usare la libreria reticolare

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

Per colori specifici

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

inserisci qui la descrizione dell'immagine

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.