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


570

我想在同一图中绘制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中做到这一点吗?


3
结帐?curve。使用add=TRUE
同构状态2015年

这个问题更具体的GGPLOT2答案。
Axeman

Answers:


617

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

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

10
为什么在下面的简单示例中不起作用?> plot(sin)> lines(cos)as.double(y)中的错误:无法将类型'builtin'强制转换为类型'double'的向量
Frank

23
这很容易看到。使用plot(sin),您将传递函数而不是实际数据。plot()将检测到此情况,然后使用plot.function()来绘制函数(在多个分派中阅读以了解更多信息)。但是,lines.function()未定义,因此lines()不知道如何处理类函数的参数。行只能处理ts类的数据和时间序列对象。
Soumendra

27
@Frank这样做:plot(sin); curve(cos, add=TRUE)
同构

2
如果x不同,如何使用相同的符号?假设我有一个图的x1和y1,并在同一图中添加了另一个x2和y2的图。x1和x2的范围相同,但值不同。
Kavipriya

1
完全相同:lines(x2,y2,...)而不是lines(x,y2,...)
bnaul

219

您还可以par在相同的图形上但在不同的轴上使用和绘制。如下所示:

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

如果您详细阅读有关par中的内容R,您将能够生成非常有趣的图表。另一本值得一看的书是Paul Murrel的R Graphics。


3
我的R给我一个错误:par(fig(new = TRUE))中的错误:找不到函数“ fig”
Alessandro Jacopson

5
您的方法是否为两个图保留了正确的比例尺(y轴)?
亚历山德罗·贾科普森

1
@uvts_cvs是的,它将原始图形保留在toto中。
山姆

10
问题在于它将重写几个绘图元素。我将xlab="", ylab="", ...在第二个中包括其他一些人plot
同构2013年

118

在构建多层地块时,应考虑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看起来像:

在此处输入图片说明

更新(2013-11-08):

正如评论中指出的那样,ggplot的哲学建议使用长格式的数据。您可以参考此答案以查看相应的代码。


5
正如Henrik建议的那样,数据确实应该采用“长”格式,ggplot比您使用的“宽”格式更自然地处理数据。
krlmlr

1
@Henrik:不,首先谢谢您的回答。也许这个答案的作者可以对其进行编辑,以使其完全符合其ggplot哲学...
krlmlr 2013年

1
@krlmlr,我尝试编辑答案,以便更明确地解决该问题。请随时建议进一步的更新。干杯。
亨里克

3
教我在ggplot(aes())上定义x,然后在geom _ *()上单独定义y。真好!

41

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

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

25
这似乎不起作用,它发出"add" is not a graphical parameter警告,然后在第一个图上打印第二个图。
Waldir Leoncio 2014年


这样做的一个好处是,它似乎使轴限制和标题保持一致。某些以前的方法使R在y轴上绘制两组刻度线,除非您麻烦指定更多选项。不用说,在轴上有两组刻度线可能会引起误解。
RMurphy '17

1
add参数适用于某些绘图方法,但不适用于R中的基础/默认方法
cloudcomputes

2
我有同样的错误"add" is not a graphical parameter。我的R是R version 3.2.3 (2015-12-10)。您可以par(new=TRUE)在这些图之间使用命令。
quepas

29

使用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 ...


25

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


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

正弦和抛物线

的输出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(如果您不记得这些是两个重要的绘图命令的名称,只需唱歌即可。)

这是curve和之间的最大区别lines

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

这是一个微小的区别:您需要尝试curve调用add=TRUE您要执行的操作,同时lines已经假设您要添加到现有绘图中。

正弦和正弦

这是的结果plot(0:2); curve(sin)


在幕后,退房methods(plot)。并检查body( plot.function )[[5]]。当您调用plot(sin)R时,sin会发现这是一个函数(不是y值)并使用plot.function方法,最终调用curvecurve用于处理功能的工具也是如此。


17

如果要将图分为两列(彼此相邻的两个图),则可以这样做:

par(mfrow=c(1,2))

plot(x)

plot(y) 

参考链接


16

如@redmode所述,您可以使用在同一图形设备中绘制两条线ggplot。在那个答案中,数据是“宽”格式的。但是,使用ggplot它通常最方便的是将数据保留在“长”格式的数据帧中。然后,通过在aes参数中线的属性(例如线型或颜色)将根据分组变量而变化,并出现相应的图例。

在这种情况下,我们可以使用colour美学方法,将线条的颜色与数据集中变量的不同级别(此处为y1 vs y2)进行匹配。但是首先,我们需要使用例如从reshape2包中“熔化”功能将数据从宽格式转换为长格式。此处介绍了其他重塑数据的方法:将data.frame从宽格式重塑为长格式

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

在此处输入图片说明


15

如果您使用的是基础图形(即不是栅格/网格图形),则可以通过使用点/线/多边形函数来模拟MATLAB的保持功能,以在不开始新绘图的情况下向绘图添加其他详细信息。如果是多图布局,则可以par(mfg=...)用来选择要添加内容的图。


14

可以将点用于叠加图。

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

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

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

除非您的数据集大小不同,否则此方法应该起作用。


这给出了:if(as.factor){:错误无法解释为逻辑
错误


5

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

在此处输入图片说明


阴暗地看起来很棒;免费吗?
丹尼斯2015年

@denis,有无限的免费公共绘图和付费私人绘图或内部部署选项。请参阅计划页面
Mateo Sanchez

4
现在,plotly R软件包是100%免费和开源的(MIT许可)。您可以在有或没有积家帐户的情况下使用它。
卡森,

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

这将创建以下图:

在此处输入图片说明


2

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

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

工作演示的屏幕截图:

在此处输入图片说明


我编译了代码,但不起作用,首先在%>%中标记了一个错误,然后将其删除,然后标记了一个错误,Error in library(plotly) : there is no package called ‘plotly’为什么?
Bellatrix

您安装了软件包plotly吗?您需要使用install.packages("plotly")命令安装软件包。
沙乌拉(Saurabh Chauhan),

1

我们也可以使用晶格库

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

对于特定颜色

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

在此处输入图片说明

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.