Trace dos gráficos en el mismo diagrama en R


572

Me gustaría trazar y1 e y2 en la misma 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")

Pero cuando lo hago así, no se trazan en la misma trama juntos.

En Matlab se puede hacer hold on, pero ¿alguien sabe cómo hacer esto en R?


3
Echa un vistazo ?curve. Uso add=TRUE.
isomorphismes

Consulte esta pregunta para obtener respuestas más específicas de ggplot2.
Axeman

Respuestas:


618

lines()o points()se agregará al gráfico existente, pero no creará una nueva ventana. Entonces deberías hacer

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

10
¿Por qué no funciona en el siguiente ejemplo simple? > plot (sin)> lines (cos) Error en as.double (y): no se puede forzar el tipo 'builtin' al vector del tipo 'double'
Frank

23
Esto es fácil de ver. Con plot (sin), está pasando una función en lugar de datos reales. plot () detectará esto y, a su vez, usar plot.function () para trazar su función (lea sobre el envío múltiple para obtener más información sobre esto). Sin embargo, lines.function () no está definido, por lo que lines () no sabe qué hacer con un parámetro de la función de clase. las líneas solo pueden tratar con sus datos y objetos de series temporales de la clase ts.
Soumendra

27
@Frank hacerlo de esta manera: plot(sin); curve(cos, add=TRUE).
isomorphismes

2
¿Cómo usar lo mismo si x es diferente? Digamos, tengo x1 e y1 para un gráfico y agrego otro gráfico de x2 e y2 en el mismo gráfico. Tanto x1 como x2 tienen el mismo rango pero valores diferentes.
Kavipriya

1
Es exactamente lo mismo: en lines(x2,y2,...)lugar delines(x,y2,...)
bnaul

220

También puede usar pary trazar en el mismo gráfico pero en diferentes ejes. Algo como sigue:

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

Si lees en detalle sobre parin R, podrás generar gráficos realmente interesantes. Otro libro para mirar es R Graphics de Paul Murrel.


3
Mi R me da un error: Error en el par (fig (new = TRUE)): no se pudo encontrar la función "fig"
Alessandro Jacopson

55
¿Su método preserva la escala correcta (eje y) para las dos parcelas?
Alessandro Jacopson

1
@uvts_cvs Sí, conserva el gráfico original en toto.
Sam

10
El problema con esto es que reescribirá varios elementos de la trama. Incluiría xlab="", ylab="", ...y algunos otros en el segundo plot.
isomorfismos

118

Al construir parcelas multicapa, uno debe considerar el ggplotpaquete. La idea es crear un objeto gráfico con una estética básica y mejorarlo gradualmente.

ggplotel estilo requiere que se empaqueten los datos data.frame.

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

Solución básica:

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

Aquí + operatorse usa para agregar capas adicionales al objeto básico.

Con ggplotusted tiene acceso a objetos gráficos en cada etapa del trazado. Digamos, la configuración habitual paso a paso puede verse así:

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, y ​​puede verla en cada etapa (bueno, después de crear al menos una capa). Otros encantamientos de la trama también se realizan con el objeto creado. Por ejemplo, podemos agregar etiquetas para ejes:

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

El final se gve así:

ingrese la descripción de la imagen aquí

ACTUALIZACIÓN (2013-11-08):

Como se señaló en los comentarios, ggplotla filosofía sugiere utilizar datos en formato largo. Puede consultar esta respuesta para ver el código correspondiente.


55
Como sugiere Henrik , los datos realmente deberían estar en formato "largo", ggplotmaneja esto de forma más natural que el formato "ancho" que utiliza.
krlmlr

1
@Henrik: No, gracias por tu respuesta en primer lugar. Tal vez el autor de esta respuesta puede modificarlo para que se ajuste bien con ggplotla filosofía 's ...
krlmlr

1
@krlmlr, intenté editar mi respuesta para que aborde más explícitamente la pregunta. Por favor, siéntase libre de sugerir nuevas actualizaciones. Salud.
Henrik

3
me enseñó a definir x en ggplot (aes ()) y luego y por sí mismo en geom _ * (). ¡Agradable!
Dan

41

Creo que la respuesta que estás buscando es:

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

25
Esto no parece funcionar, da una "add" is not a graphical parameteradvertencia y luego imprime el segundo diagrama sobre el primero.
Waldir Leoncio


Un buen beneficio de esto es que parece mantener consistentes los límites de los ejes y los títulos. Algunos de los métodos anteriores hacen que R dibuje dos conjuntos de marcas en el eje y, a menos que tenga problemas para especificar más opciones. No hace falta decir que tener dos conjuntos de marcas en los ejes podría ser muy engañoso.
RMurphy

1
el parámetro add funciona para algunos métodos de trazado, pero no el base / predeterminado en R
cloudscomputes

2
Tengo el mismo error "add" is not a graphical parameter. Mi R es R version 3.2.3 (2015-12-10). Puede usar el par(new=TRUE)comando entre estas parcelas.
quepas

29

Usa la matplotfunción:

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

use esto si y1y y2se evalúan en los mismos xpuntos. Escala el eje Y para que se ajuste al que sea más grande ( y1o y2), a diferencia de algunas de las otras respuestas aquí que se recortarán y2si se hace más grande que y1(las soluciones de ggplot en su mayoría están bien con esto).

Alternativamente, y si las dos líneas no tienen las mismas coordenadas x, establezca los límites del eje en el primer diagrama y agregue:

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

Me sorprende que este Q tenga 4 años y nadie lo haya mencionado matploto x/ylim...


25

tl; dr: desea usar curve(con add=TRUE) o lines.


No estoy de acuerdo con par(new=TRUE)porque eso imprimirá dos marcas de graduación y etiquetas de eje. P.ej

seno y parábola

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

¡Mira lo desordenadas que están las etiquetas del eje vertical! Dado que los rangos son diferentes, necesitaría establecerlos ylim=c(lowest point between the two functions, highest point between the two functions), lo cual es menos fácil de lo que estoy a punto de mostrarle, y mucho menos fácil si desea agregar no solo dos curvas, sino muchas.


Lo que siempre me confundió acerca de trazar es la diferencia entre curvey lines. (Si no puede recordar que estos son los nombres de los dos comandos de trazado importantes, simplemente cántelo ).

Aquí está la gran diferencia entre curvey lines.

curvetrazará una función, como curve(sin). linesparcelas puntos con valores x e y, como: lines( x=0:10, y=sin(0:10) ).

Y aquí hay una pequeña diferencia: curvedebe llamarse con add=TRUElo que está tratando de hacer, mientras que linesya asume que está agregando a una trama existente.

id y seno

Aquí está el resultado de llamar plot(0:2); curve(sin).


Detrás de escena, echa un vistazo methods(plot). Y verifica body( plot.function )[[5]]. Cuando llamas a plot(sin)R, descubres que sines una función (no valores de y) y usa el plot.functionmétodo, que termina llamando curve. Así curvees la herramienta destinada a manejar funciones.


17

Si desea dividir la trama en dos columnas (2 parcelas una al lado de la otra), puede hacerlo así:

par(mfrow=c(1,2))

plot(x)

plot(y) 

Link de referencia


16

Según lo descrito por @redmode, puede trazar las dos líneas en el mismo dispositivo gráfico usando ggplot. En esa respuesta, los datos estaban en un formato 'ancho'. Sin embargo, cuando se usa ggplotgeneralmente es más conveniente mantener los datos en un marco de datos en un formato 'largo'. Luego, mediante el uso de diferentes 'variables de agrupación' en los aesargumentos de temas, las propiedades de la línea, como el tipo de línea o el color, variarán de acuerdo con la variable de agrupación, y aparecerán las leyendas correspondientes.

En este caso, podemos usar la colourestética, que hace coincidir el color de las líneas con diferentes niveles de una variable en el conjunto de datos (aquí: y1 vs y2). Pero primero necesitamos derretir los datos de formato ancho a largo, usando, por ejemplo, la función 'derretir' del reshape2paquete. Aquí se describen otros métodos para remodelar los datos: Reformar data.frame de formato ancho a largo .

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

ingrese la descripción de la imagen aquí


15

Si está utilizando gráficos base (es decir, no gráficos de cuadrícula / cuadrícula), puede imitar la función de retención de MATLAB utilizando las funciones de puntos / líneas / polígonos para agregar detalles adicionales a sus gráficos sin comenzar un nuevo gráfico. En el caso de un diseño multiplot, puede usar par(mfg=...)para elegir a qué gráfico agregar cosas.


14

Puede usar puntos para la sobreparcela, es decir.

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

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

7

En lugar de mantener los valores que se trazarán en una matriz, almacénelos en una matriz. Por defecto, toda la matriz se tratará como un conjunto de datos. Sin embargo, si agrega la misma cantidad de modificadores al gráfico, por ejemplo, col (), ya que tiene filas en la matriz, R descubrirá que cada fila debe tratarse de forma independiente. Por ejemplo:

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

Esto debería funcionar a menos que sus conjuntos de datos sean de diferentes tamaños.


Esto da: Error en if (as.factor) {: argumento no es interpretable como lógico
baouss


5

Podría usar la ggplotly()función del paquete plotly para convertir cualquiera de los ejemplos de gggplot2 aquí en un diagrama interactivo, pero creo que este tipo de diagrama es mejor sin 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")

ingrese la descripción de la imagen aquí


tramadamente se ve brillante; es gratis ?
denis

@denis, hay una trama pública gratuita ilimitada y una trama privada pagada u opciones locales. Ver la página de planes .
Mateo Sánchez

44
El paquete plotly R ahora es 100% gratuito y de código abierto (licencia MIT). Puede usarlo con o sin una cuenta gráfica.
Carson el

4

También puede crear su 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')

Esto creará la siguiente trama:

ingrese la descripción de la imagen aquí


2

Usando plotly(agregando solución desde el plotlyeje y primario y secundario- Parece que falta):

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

Captura de pantalla de la demostración de trabajo:

ingrese la descripción de la imagen aquí


Compilé el código y no funciona, primero marqué un error en%>% y lo eliminé, luego marqué un error Error in library(plotly) : there is no package called ‘plotly’¿por qué?
Bellatrix

¿Has instalado el paquete plotly? Necesita instalar el paquete usando el install.packages("plotly")comando.
Saurabh Chauhan

1

también podemos usar la biblioteca de celosía

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

Para colores específicos

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

ingrese la descripción de la imagen aquí

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.