[英]Plot two graphs in same plot in R
I would like to plot y1 and y2 in the same plot.我想 plot y1 和 y2 在同一个 plot。
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")
But when I do it like this, they are not plotted in the same plot together.但是当我这样做时,它们不会一起绘制在同一个 plot 中。
In Matlab one can do hold on
, but does anyone know how to do this in R?在 Matlab 中可以hold on
,但有谁知道如何在 R 中做到这一点?
lines()
or points()
will add to the existing graph, but will not create a new window. lines()
或points()
将添加到现有图形,但不会创建新窗口。 So you'd need to do所以你需要做
plot(x,y1,type="l",col="red")
lines(x,y2,col="green")
You can also use par
and plot on the same graph but different axis.您还可以在同一个图形但不同的轴上使用par
和 plot。 Something as follows:如下:
plot( x, y1, type="l", col="red" )
par(new=TRUE)
plot( x, y2, type="l", col="green" )
If you read in detail about par
in R
, you will be able to generate really interesting graphs.如果您详细阅读R
par
,您将能够生成非常有趣的图形。 Another book to look at is Paul Murrel's R Graphics.另一本书是 Paul Murrel 的 R Graphics。
When constructing multilayer plots one should consider ggplot
package.在构建多层图时,应考虑使用ggplot
包。 The idea is to create a graphical object with basic aesthetics and enhance it incrementally.这个想法是创建一个具有基本美学的图形对象并逐步增强它。
ggplot
style requires data to be packed in data.frame
. 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)
Basic solution:基本解决方案:
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
Here + operator
is used to add extra layers to basic object.这里+ operator
用于向基本对象添加额外的图层。
With ggplot
you have access to graphical object on every stage of plotting.使用ggplot
您可以在绘图的每个阶段访问图形对象。 Say, usual step-by-step setup can look like this:比如说,通常的分步设置可能如下所示:
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
produces the plot, and you can see it at every stage (well, after creation of at least one layer). g
生成绘图,您可以在每个阶段看到它(好吧,在创建至少一层之后)。 Further enchantments of the plot are also made with created object.情节的进一步附魔也由创建的对象制成。 For example, we can add labels for axises:例如,我们可以为轴添加标签:
g <- g + ylab("Y") + xlab("X")
g
Final g
looks like:最后的g
看起来像:
UPDATE (2013-11-08):更新(2013-11-08):
As pointed out in comments, ggplot
's philosophy suggests using data in long format.正如评论中指出的那样, ggplot
的哲学建议使用长格式的数据。 You can refer to this answer in order to see the corresponding code.您可以参考此答案以查看相应的代码。
I think that the answer you are looking for is:我认为您正在寻找的答案是:
plot(first thing to plot)
plot(second thing to plot,add=TRUE)
Use the matplot
function:使用matplot
函数:
matplot(x, cbind(y1,y2),type="l",col=c("red","green"),lty=c(1,1))
use this if y1
and y2
are evaluated at the same x
points.如果y1
和y2
在相同的x
点计算,则使用此选项。 It scales the Y-axis to fit whichever is bigger ( y1
or y2
), unlike some of the other answers here that will clip y2
if it gets bigger than y1
(ggplot solutions mostly are okay with this).它缩放 Y 轴以适应较大的( y1
或y2
),这与此处的其他一些答案不同,如果y2
大于y1
则会裁剪y2
(ggplot 解决方案大多对此没问题)。
Alternatively, and if the two lines don't have the same x-coordinates, set the axis limits on the first plot and add:或者,如果两条线没有相同的 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")
Am astonished this Q is 4 years old and nobody has mentioned matplot
or x/ylim
...我很惊讶这个 Q 已经 4 岁了,没有人提到过matplot
或x/ylim
......
tl;dr: You want to use curve
(with add=TRUE
) or lines
. tl;dr:您想使用curve
(带有add=TRUE
)或lines
。
I disagree with par(new=TRUE)
because that will double-print tick-marks and axis labels.我不同意par(new=TRUE)
因为这会重复打印刻度线和轴标签。 Eg例如
The output of plot(sin); par(new=T); plot( function(x) x**2 )
plot(sin); par(new=T); plot( function(x) x**2 )
的输出plot(sin); par(new=T); plot( function(x) x**2 )
plot(sin); par(new=T); plot( function(x) x**2 )
plot(sin); par(new=T); plot( function(x) x**2 )
. plot(sin); par(new=T); plot( function(x) x**2 )
。
Look how messed up the vertical axis labels are!看看垂直轴标签有多乱! Since the ranges are different you would need to set ylim=c(lowest point between the two functions, highest point between the two functions)
, which is less easy than what I'm about to show you---and way less easy if you want to add not just two curves, but many.由于范围是不同的,你需要设置ylim=c(lowest point between the two functions, highest point between the two functions)
的方式,这是不容易比我要告诉你---并不太容易,如果您不仅要添加两条曲线,还要添加许多曲线。
What always confused me about plotting is the difference between curve
and lines
.绘图时总是让我感到困惑的是curve
和lines
之间的区别。 (If you can't remember that these are the names of the two important plotting commands, just sing it.) (如果你不记得这些是两个重要绘图命令的名称,就唱出来。)
curve
and lines
.这是curve
和lines
之间的巨大区别。 curve
will plot a function, like curve(sin)
. curve
将绘制一个函数,如curve(sin)
。 lines
plots points with x and y values, like: lines( x=0:10, y=sin(0:10) )
. lines
用 x 和 y 值绘制点,例如: lines( x=0:10, y=sin(0:10) )
。
And here's a minor difference: curve
needs to be called with add=TRUE
for what you're trying to do, while lines
already assumes you're adding to an existing plot.这里有一个细微的区别:对于您要执行的操作,需要使用add=TRUE
调用curve
,而lines
已经假定您要添加到现有绘图中。
Here's the result of calling plot(0:2); curve(sin)
这是调用plot(0:2); curve(sin)
的结果plot(0:2); curve(sin)
plot(0:2); curve(sin)
. plot(0:2); curve(sin)
。
Behind the scenes, check out methods(plot)
.在幕后,查看methods(plot)
。 And check body( plot.function )[[5]]
.并检查body( plot.function )[[5]]
。 When you call plot(sin)
R figures out that sin
is a function (not y values) and uses the plot.function
method, which ends up calling curve
.当您调用plot(sin)
R 时,会发现sin
是一个函数(不是 y 值)并使用plot.function
方法,该方法最终调用了curve
。 So curve
is the tool meant to handle functions.所以curve
是用来处理函数的工具。
if you want to split the plot into two columns (2 plots next to each other), you can do it like this:如果您想将绘图分成两列(2 个相邻的绘图),您可以这样做:
par(mfrow=c(1,2))
plot(x)
plot(y)
As described by @redmode, you may plot the two lines in the same graphical device using ggplot
.如@redmode 所述,您可以使用ggplot
在同一图形设备中绘制两条线。 In that answer the data were in a 'wide' format.在那个答案中,数据采用“宽”格式。 However, when using ggplot
it is generally most convenient to keep the data in a data frame in a 'long' format.但是,在使用ggplot
,通常最方便的是将数据以“长”格式保存在数据框中。 Then, by using different 'grouping variables' in the aes
thetics arguments, properties of the line, such as linetype or colour, will vary according to the grouping variable, and corresponding legends will appear.然后,通过在使用不同的“分组变量” aes
thetics参数,线路的特性,如线型或颜色,将根据分组变量而变化,并且对应的图例将出现。
In this case, we can use the colour
aessthetics, which matches colour of the lines to different levels of a variable in the data set (here: y1 vs y2).在这种情况下,我们可以使用colour
美学,它将线条的颜色与数据集中变量的不同级别相匹配(此处:y1 与 y2)。 But first we need to melt the data from wide to long format, using eg the function 'melt' from reshape2
package.但首先我们需要将数据从宽格式转换为长格式,例如使用reshape2
包中的函数“melt”。 Other methods to reshape the data are described here: Reshaping data.frame from wide to long format .此处描述了重塑数据的其他方法: 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()
If you are using base graphics (ie not lattice/ grid graphics), then you can mimic MATLAB's hold on feature by using the points/lines/polygons functions to add additional details to your plots without starting a new plot.如果您使用的是基础图形(即不是点阵/网格图形),那么您可以通过使用点/线/多边形函数来模拟 MATLAB 的保持功能,在不开始新绘图的情况下向绘图添加其他细节。 In the case of a multiplot layout, you can use par(mfg=...)
to pick which plot you add things to.在多图布局的情况下,您可以使用par(mfg=...)
来选择要添加内容的图。
You can use points for the overplot, that is.您可以使用点进行叠加,即。
plot(x1, y1,col='red')
points(x2,y2,col='blue')
Rather than keeping the values to be plotted in an array, store them in a matrix.不是将要绘制的值保存在数组中,而是将它们存储在矩阵中。 By default the entire matrix will be treated as one data set.默认情况下,整个矩阵将被视为一个数据集。 However if you add the same number of modifiers to the plot, eg the col(), as you have rows in the matrix, R will figure out that each row should be treated independently.但是,如果您向图中添加相同数量的修饰符,例如 col(),因为您在矩阵中有行,R 将计算出应独立处理每一行。 For example:例如:
x = matrix( c(21,50,80,41), nrow=2 )
y = matrix( c(1,2,1,2), nrow=2 )
plot(x, y, col("red","blue")
This should work unless your data sets are of differing sizes.除非您的数据集大小不同,否则这应该有效。
You could use the ggplotly()
function from the plotly package to turn any of the gggplot2 examples here into an interactive plot, but I think this sort of plot is better without ggplot2 :您可以使用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")
Idiomatic Matlab plot(x1,y1,x2,y2)
can be translated in R with ggplot2
for example in this way:惯用的 Matlab plot(x1,y1,x2,y2)
可以在 R 中使用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))
Inspired by Tingting Zhao's Dual line plots with different range of x-axis Using ggplot2 .受到 Tingting Zhao 的使用 ggplot2 的不同 x 轴范围的双线图的启发。
You can also create your plot using ggvis :您还可以使用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')
This will create the following plot:这将创建以下图:
Using plotly
(adding solution from plotly
with primary and secondary y axis- It seems to be missing):使用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))
Screenshot from working demo:工作演示的截图:
we can also use lattice library我们也可以使用格子库
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))
For specific colors对于特定颜色
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"))))
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.