在单个图中绘制4条曲线,并使用3个y轴。

26
我有4组数值:y1、y2、y3、y4和一个数值x。这些y值范围不同,我需要将它们作为分离的曲线绘制到y轴上,并使用各自的数据集。
简而言之,我需要在同一图表上绘制具有不同值(刻度)的3个y轴。

我不太清楚你确切想要什么。也许包含一些 ASCII 艺术(或图像)模拟会有所帮助,以便更好地了解它应该是什么样子的。此外,您可以查看 R 图库(http://addictedtor.free.fr/graphiques/RGraphGallery.php),看看哪个最接近。 - phooji
3个回答

30

尝试一下这个...

# The data have a common independent variable (x)
x <- 1:10

# Generate 4 different sets of outputs
y1 <- runif(10, 0, 1)
y2 <- runif(10, 100, 150)
y3 <- runif(10, 1000, 2000)
y4 <- runif(10, 40000, 50000)
y <- list(y1, y2, y3, y4)

# Colors for y[[2]], y[[3]], y[[4]] points and axes
colors = c("red", "blue", "green")

# Set the margins of the plot wider
par(oma = c(0, 2, 2, 3))

plot(x, y[[1]], yaxt = "n", xlab = "Common x-axis", main = "A bunch of plots on the same graph", 
     ylab = "")
lines(x, y[[1]])

# We use the "pretty" function go generate nice axes
axis(at = pretty(y[[1]]), side = 2)

# The side for the axes.  The next one will go on 
# the left, the following two on the right side
sides <- list(2, 4, 4) 

# The number of "lines" into the margin the axes will be
lines <- list(2, NA, 2)

for(i in 2:4) {
  par(new = TRUE)
  plot(x, y[[i]], axes = FALSE, col = colors[i - 1], xlab = "", ylab = "")
  axis(at = pretty(y[[i]]), side = sides[[i-1]], line = lines[[i-1]], 
      col = colors[i - 1])
  lines(x, y[[i]], col = colors[i - 1])
}

# Profit.

绘图输出


2
我对这里展示的R-fu印象深刻,但个人无法理解所得到的产品。也许如果除了颜色之外还使用不同的符号,或者替换颜色,会更加清晰。或者这只是随机数据显示的产物...无论如何 - 做得好!(+1) - Chase
1
@Chase 我是在一段时间前从某个博客上得到这个想法的,但我希望我当时保存了链接。我刚刚添加了连接点的线条。实际上,我必须说,这些线条清楚地表明了为什么其他答案在大多数情况下更好。在同一图中绘制多个图表可能会产生误导,只有在我们有一组输出以大致相同的方式增加/减少时(即我用这种图表来表示甲烷气体和环境中的二氧化碳)才是一个好方法。 - Rguy

22
如果你想学习超出基础图形之外的绘图包,这里是使用 @Rguy 答案中的变量并采用 ggplot2 的解决方案:
library(ggplot2)
dat <- data.frame(x, y1, y2, y3, y4)

dat.m <- melt(dat, "x")

ggplot(dat.m, aes(x, value, colour = variable)) + geom_line() +
facet_wrap(~ variable, ncol = 1, scales = "free_y") +
scale_colour_discrete(legend = FALSE)

在这里输入图像描述


这种布局比接受的答案更合乎逻辑,但它确实取决于原始问题的具体情况。 - naught101
非常感谢您的评论!但是,我需要在aes部分添加group=1。否则,它会抛出“geom_path:每个组仅包含一个观察结果。您需要调整组美学吗?”错误。 - Vasyl Laver

18

尝试以下方法,它并不像看上去那么复杂。一旦您观看了第一个图形被构建的过程,您会发现其他图形非常相似。由于有四个类似的图形,您可以很容易地重新配置代码为一个函数,用于反复绘制每个图形。但是,由于我通常绘制具有相同x轴的各种图形,我需要很高的灵活性。因此,我决定对于每个图形只需复制/粘贴/修改代码更容易些。

#Generate the data for the four graphs
x <- seq(1, 50, 1)
y1 <- 10*rnorm(50)
y2 <- 100*rnorm(50)
y3 <- 1000*rnorm(50)
y4 <- 10000*rnorm(50)

#Set up the plot area so that multiple graphs can be crammed together
par(pty="m", plt=c(0.1, 1, 0, 1), omd=c(0.1,0.9,0.1,0.9))

#Set the area up for 4 plots
par(mfrow = c(4, 1))

#Plot the top graph with nothing in it =========================
plot(x, y1, xlim=range(x), type="n", xaxt="n", yaxt="n", main="", xlab="", ylab="")
mtext("Four Y Plots With the Same X", 3, line=1, cex=1.5)

#Store the x-axis data of the top plot so it can be used on the other graphs
pardat<-par()
xaxisdat<-seq(pardat$xaxp[1],pardat$xaxp[2],(pardat$xaxp[2]-pardat$xaxp[1])/pardat$xaxp[3])

#Get the y-axis data and add the lines and label
yaxisdat<-seq(pardat$yaxp[1],pardat$yaxp[2],(pardat$yaxp[2]-pardat$yaxp[1])/pardat$yaxp[3])
axis(2, at=yaxisdat, las=2, padj=0.5, cex.axis=0.8, hadj=0.5, tcl=-0.3)
abline(v=xaxisdat, col="lightgray")
abline(h=yaxisdat, col="lightgray")
mtext("y1", 2, line=2.3)
lines(x, y1, col="red")

#Plot the 2nd graph with nothing ================================
plot(x, y2, xlim=range(x), type="n", xaxt="n", yaxt="n", main="", xlab="", ylab="")

#Get the y-axis data and add the lines and label
pardat<-par()
yaxisdat<-seq(pardat$yaxp[1],pardat$yaxp[2],(pardat$yaxp[2]-pardat$yaxp[1])/pardat$yaxp[3])
axis(2, at=yaxisdat, las=2, padj=0.5, cex.axis=0.8, hadj=0.5, tcl=-0.3)
abline(v=xaxisdat, col="lightgray")
abline(h=yaxisdat, col="lightgray")
mtext("y2", 2, line=2.3)
lines(x, y2, col="blue")

#Plot the 3rd graph with nothing =================================
plot(x, y3, xlim=range(x), type="n", xaxt="n", yaxt="n", main="", xlab="", ylab="")

#Get the y-axis data and add the lines and label
pardat<-par()
yaxisdat<-seq(pardat$yaxp[1],pardat$yaxp[2],(pardat$yaxp[2]-pardat$yaxp[1])/pardat$yaxp[3])
axis(2, at=yaxisdat, las=2, padj=0.5, cex.axis=0.8, hadj=0.5, tcl=-0.3)
abline(v=xaxisdat, col="lightgray")
abline(h=yaxisdat, col="lightgray")
mtext("y3", 2, line=2.3)
lines(x, y3, col="green")

#Plot the 4th graph with nothing =================================
plot(x, y4, xlim=range(x), type="n", xaxt="n", yaxt="n", main="", xlab="", ylab="")

#Get the y-axis data and add the lines and label
pardat<-par()
yaxisdat<-seq(pardat$yaxp[1],pardat$yaxp[2],(pardat$yaxp[2]-pardat$yaxp[1])/pardat$yaxp[3])
axis(2, at=yaxisdat, las=2, padj=0.5, cex.axis=0.8, hadj=0.5, tcl=-0.3)
abline(v=xaxisdat, col="lightgray")
abline(h=yaxisdat, col="lightgray")
mtext("y4", 2, line=2.3)
lines(x, y4, col="darkgray")

#Plot the X axis =================================================
axis(1, at=xaxisdat, padj=-1.4, cex.axis=0.9, hadj=0.5, tcl=-0.3)
mtext("X Variable", 1, line=1.5)

下面是四个图表的绘制结果。

enter image description here


2
这也是一个很好的解决方案。我可能会在某个时候使用它。这比将所有点放在完全相同的图表上要少误导性。 - Rguy

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接