在R中的相同图中绘制两个图

时间:2010-04-01 23:28:14

标签: r plot ggplot2 r-faq

我想在同一个情节中绘制y1和y2。

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

但是,当我这样做的时候,它们并没有被绘制在同一个地块中。

在Matlab中可以做hold on,但有人知道如何在R中做到这一点吗?

16 个答案:

答案 0 :(得分:543)

lines()points()会添加到现有图表中,但不会创建新窗口。所以你需要做

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

答案 1 :(得分:194)

您也可以使用par并绘制相同的图表但不同的轴。如下:

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

如果您在par中详细了解R,您将能够生成非常有趣的图表。另一本值得关注的书是Paul Murrel的R Graphics。

答案 2 :(得分:104)

构建多层图时,应考虑ggplot包。我们的想法是创建一个具有基本美学的图形对象,并逐步增强它。

ggplot样式要求将数据打包在data.frame

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

基本解决方案:

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

此处+ operator用于向基本对象添加额外的图层。

使用ggplot,您可以在绘图的每个阶段访问图形对象。比方说,通常的逐步设置可能如下所示:

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

g生成绘图,您可以在每个阶段(在创建至少一个图层之后)看到它。绘图的进一步附魔也是用创建的对象进行的。例如,我们可以为轴添加标签:

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

最终g看起来像:

enter image description here

更新时间(2013-11-08):

正如评论中所指出的那样,ggplot的哲学建议使用长格式的数据。 您可以参考此答案https://stackoverflow.com/a/19039094/1796914以查看相应的代码。

答案 3 :(得分:35)

我认为您正在寻找的答案是:

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

答案 4 :(得分:25)

使用matplot功能:

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

如果y1y2在同一x点进行评估,请使用此功能。它会缩放Y轴以适合更大的值(y1y2),与此处的其他一些答案不同,如果它变得大于y2,它将剪切y1 (ggplot解决方案大多数都可以。)

或者,如果两条线没有相同的x坐标,请在第一个图上设置轴限制并添加:

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

很惊讶这个Q已经4岁了,没有人提到matplotx/ylim ......

答案 5 :(得分:23)

tl; dr:您想使用curve(使用add=TRUE)或lines


我不同意par(new=TRUE),因为这会打印刻度线和轴标签。例如

sine and parabola

plot(sin); par(new=T); plot( function(x) x**2 )的输出。

看看垂直轴标签是多么混乱!由于范围不同,您需要设置ylim=c(lowest point between the two functions, highest point between the two functions),这比我要向您展示的要简单得多 - 如果您想添加方式则不那么容易不只是两条曲线,而是很多曲线。


总是让我对绘图感到困惑的是curvelines之间的区别。 (如果你不记得这些是两个重要绘图命令的名称,只需要sing它。)

这里curvelines之间存在很大差异。

curve会绘制一个函数,例如curve(sin)lines用x和y值绘制点,例如:lines( x=0:10, y=sin(0:10) )

这里有一个小小的差异:curve需要使用add=TRUE来调用你正在尝试做的事情,而lines已经假设你了。重新加入现有的情节。

id & sine

以下是调用plot(0:2); curve(sin)的结果。


在幕后,查看methods(plot)。并检查body( plot.function )[[5]]。当您致电plot(sin)时,R会发现sin是一个函数(不是y值),并使用plot.function方法,最终调用curve。所以curve是用于处理函数的工具。

答案 6 :(得分:16)

如@redmode所述,您可以使用ggplot在同一图形设备中绘制两条线。在该答案中,数据采用“宽”格式。但是,使用ggplot时,通常最方便的是将数据保存在“长”格式的数据框中。然后,通过在aes thetics参数中使用不同的“分组变量”,该行的属性(如线型或颜色)将根据分组变量而变化,并且将显示相应的图例。

在这种情况下,我们可以使用colour aessthetics,它将行的颜色与数据集中变量的不同级别匹配(此处:y1 vs y2)。但首先我们需要将数据从宽格式转换为长格式,例如使用例如来自reshape2包的函数'melt'。其他重塑数据的方法如下所述:Reshaping data.frame from wide to long format

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

enter image description here

答案 7 :(得分:15)

如果您正在使用基本图形(即非格子/网格图形),则可以使用点/线/多边形函数模拟MATLAB的保持特征,以便在不创建新图的情况下向图中添加其他详细信息。对于多画布布局,您可以使用par(mfg=...)选择要添加内容的绘图。

答案 8 :(得分:14)

如果要拆分屏幕,可以这样做:

(例如,下面的2个地块)

par(mfrow=c(1,2))

plot(x)

plot(y) 

Reference Link

答案 9 :(得分:12)

你可以使用点作为上图,即。

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

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

答案 10 :(得分:7)

不是将值保存在数组中,而是将它们存储在矩阵中。默认情况下,整个矩阵将被视为一个数据集。但是,如果向绘图添加相同数量的修改器,例如col(),因为矩阵中有行,R将确定应该独立处理每一行。例如:

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

除非您的数据集具有不同的大小,否则这应该有效。

答案 11 :(得分:5)

惯用法Matlab ggplot2可以用x1 <- seq(1,10,.2) df1 <- data.frame(x=x1,y=log(x1),type="Log") x2 <- seq(1,10) df2 <- data.frame(x=x2,y=cumsum(1/x2),type="Harmonic") df <- rbind(df1,df2) library(ggplot2) ggplot(df)+geom_line(aes(x,y,colour=type)) 翻译成R,例如:

FileField

enter image description here

受婷婷的Dual line plots with different range of x-axis Using ggplot2的启发。

答案 12 :(得分:4)

您还可以使用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')

这将创建以下图:

enter image description here

答案 13 :(得分:3)

您可以使用 plotly 包中的ggplotly()函数将此处的任何 gggplot2 示例转换为交互式图,但我认为这种没有 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")

enter image description here

答案 14 :(得分:1)

我们还可以使用晶格库

spn:00000002-0000-0000-c000-000000000000

对于特定颜色

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

enter image description here

答案 15 :(得分:1)

使用plotly(从具有主要和次要y轴的plotly添加解决方案-似乎丢失了):

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

正在运行的演示的屏幕截图:

enter image description here