131

我想在 R 中叠加两个散点图,以便每组点都有自己的(不同的)y 轴(即,在图中的位置 2 和 4),但这些点似乎叠加在同一个图上。

有可能做到这一点plot吗?

编辑显示问题的示例代码

# example code for SO question
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)
x <- 1:10
# in this plot y2 is plotted on what is clearly an inappropriate scale
plot(y1 ~ x, ylim = c(-1, 150))
points(y2 ~ x, pch = 2)
4

6 回答 6

139

更新:在http://rwiki.sciviews.org/doku.php?id=tips:graphics-base:2yaxes上的 R wiki 上复制的材料,链接现在已损坏:也可从Wayback 机器获得

同一图上有两个不同的 y 轴

(一些材料最初由 Daniel Rajdl 2006/03/31 15:26)

请注意,很少有情况适合在同一个地块上使用两种不同的尺度。很容易误导图形的查看者。检查以下两个示例和对此问题的评论(来自Junk Charts的example1example2),以及Stephen Few 的这篇文章(其结论是“我当然不能一劳永逸地得出结论,具有双比例轴的图形永远不会有用;只是我想不出有什么情况可以根据其他更好的解决方案来保证他们。”)另请参阅本漫画中的第 4 点...

如果你确定了,基本的方法是创建你的第一个图,设置par(new=TRUE)为防止 R 清除图形设备,创建第二个图(并axes=FALSE设置为空白 -也应该有效),然后使用添加一个新轴在右侧,并在右侧添加轴标签。这是一个使用少量虚构数据的示例:xlabylabann=FALSEaxis(side=4)mtext(...,side=4)

set.seed(101)
x <- 1:10
y <- rnorm(10)
## second data set on a very different scale
z <- runif(10, min=1000, max=10000) 
par(mar = c(5, 4, 4, 4) + 0.3)  # Leave space for z axis
plot(x, y) # first plot
par(new = TRUE)
plot(x, z, type = "l", axes = FALSE, bty = "n", xlab = "", ylab = "")
axis(side=4, at = pretty(range(z)))
mtext("z", side=4, line=3)

twoord.plot()plotrix包中自动执行此过程,就像doubleYScale()latticeExtra包中一样。

另一个例子(改编自 Robert W. Baer 的 R 邮件列表帖子):

## set up some fake test data
time <- seq(0,72,12)
betagal.abs <- c(0.05,0.18,0.25,0.31,0.32,0.34,0.35)
cell.density <- c(0,1000,2000,3000,4000,5000,6000)

## add extra space to right margin of plot within frame
par(mar=c(5, 4, 4, 6) + 0.1)

## Plot first set of data and draw its axis
plot(time, betagal.abs, pch=16, axes=FALSE, ylim=c(0,1), xlab="", ylab="", 
   type="b",col="black", main="Mike's test data")
axis(2, ylim=c(0,1),col="black",las=1)  ## las=1 makes horizontal labels
mtext("Beta Gal Absorbance",side=2,line=2.5)
box()

## Allow a second plot on the same graph
par(new=TRUE)

## Plot the second plot and put axis scale on right
plot(time, cell.density, pch=15,  xlab="", ylab="", ylim=c(0,7000), 
    axes=FALSE, type="b", col="red")
## a little farther out (line=4) to make room for labels
mtext("Cell Density",side=4,col="red",line=4) 
axis(4, ylim=c(0,7000), col="red",col.axis="red",las=1)

## Draw the time axis
axis(1,pretty(range(time),10))
mtext("Time (Hours)",side=1,col="black",line=2.5)  

## Add Legend
legend("topleft",legend=c("Beta Gal","Cell Density"),
  text.col=c("black","red"),pch=c(16,15),col=c("black","red"))

在此处输入图像描述

类似的配方可用于叠加不同类型的图——条形图、直方图等。

于 2011-05-26T18:20:46.337 回答
36

顾名思义,twoord.plot()plotrix包中,有两个纵坐标轴。

library(plotrix)
example(twoord.plot)

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

在此处输入图像描述

于 2011-05-26T18:15:09.573 回答
5

一种选择是并排制作两个地块。ggplot2为此提供了一个不错的选择facet_wrap()

dat <- data.frame(x = c(rnorm(100), rnorm(100, 10, 2))
  , y = c(rnorm(100), rlnorm(100, 9, 2))
  , index = rep(1:2, each = 100)
  )

require(ggplot2)
ggplot(dat, aes(x,y)) + 
geom_point() + 
facet_wrap(~ index, scales = "free_y")
于 2011-05-26T18:00:56.453 回答
5

如果您可以放弃刻度/轴标签,则可以将数据重新缩放到 (0, 1) 间隔。例如,这适用于染色体上不同的“摆动”轨迹,当您通常对轨迹之间的局部相关性感兴趣并且它们具有不同的尺度(以千计,Fst 0-1)时。

# rescale numeric vector into (0, 1) interval
# clip everything outside the range 
rescale <- function(vec, lims=range(vec), clip=c(0, 1)) {
  # find the coeficients of transforming linear equation
  # that maps the lims range to (0, 1)
  slope <- (1 - 0) / (lims[2] - lims[1])
  intercept <- - slope * lims[1]

  xformed <- slope * vec + intercept

  # do the clipping
  xformed[xformed < 0] <- clip[1]
  xformed[xformed > 1] <- clip[2]

  xformed
}

然后,拥有一个包含 、 和 列的数据框chrom,您position可以执行以下操作:coveragefst

ggplot(d, aes(position)) + 
  geom_line(aes(y = rescale(fst))) + 
  geom_line(aes(y = rescale(coverage))) +
  facet_wrap(~chrom)

这样做的好处是你不限于两个 trakcs。

于 2015-04-02T20:15:49.683 回答
4

我也建议,twoord.stackplot()plotrix包含两个纵坐标轴的包图中。

data<-read.table(text=
"e0AL fxAL e0CO fxCO e0BR fxBR anos
 51.8  5.9 50.6  6.8 51.0  6.2 1955
 54.7  5.9 55.2  6.8 53.5  6.2 1960
 57.1  6.0 57.9  6.8 55.9  6.2 1965
 59.1  5.6 60.1  6.2 57.9  5.4 1970
 61.2  5.1 61.8  5.0 59.8  4.7 1975
 63.4  4.5 64.0  4.3 61.8  4.3 1980
 65.4  3.9 66.9  3.7 63.5  3.8 1985
 67.3  3.4 68.0  3.2 65.5  3.1 1990
 69.1  3.0 68.7  3.0 67.5  2.6 1995
 70.9  2.8 70.3  2.8 69.5  2.5 2000
 72.4  2.5 71.7  2.6 71.1  2.3 2005
 73.3  2.3 72.9  2.5 72.1  1.9 2010
 74.3  2.2 73.8  2.4 73.2  1.8 2015
 75.2  2.0 74.6  2.3 74.2  1.7 2020
 76.0  2.0 75.4  2.2 75.2  1.6 2025
 76.8  1.9 76.2  2.1 76.1  1.6 2030
 77.6  1.9 76.9  2.1 77.1  1.6 2035
 78.4  1.9 77.6  2.0 77.9  1.7 2040
 79.1  1.8 78.3  1.9 78.7  1.7 2045
 79.8  1.8 79.0  1.9 79.5  1.7 2050
 80.5  1.8 79.7  1.9 80.3  1.7 2055
 81.1  1.8 80.3  1.8 80.9  1.8 2060
 81.7  1.8 80.9  1.8 81.6  1.8 2065
 82.3  1.8 81.4  1.8 82.2  1.8 2070
 82.8  1.8 82.0  1.7 82.8  1.8 2075
 83.3  1.8 82.5  1.7 83.4  1.9 2080
 83.8  1.8 83.0  1.7 83.9  1.9 2085
 84.3  1.9 83.5  1.8 84.4  1.9 2090
 84.7  1.9 83.9  1.8 84.9  1.9 2095
 85.1  1.9 84.3  1.8 85.4  1.9 2100", header=T)

require(plotrix)
twoord.stackplot(lx=data$anos, rx=data$anos, 
                 ldata=cbind(data$e0AL, data$e0BR, data$e0CO),
                 rdata=cbind(data$fxAL, data$fxBR, data$fxCO),
                 lcol=c("black","red", "blue"),
                 rcol=c("black","red", "blue"), 
                 ltype=c("l","o","b"),
                 rtype=c("l","o","b"), 
                 lylab="Años de Vida", rylab="Hijos x Mujer", 
                 xlab="Tiempo",
                 main="Mortalidad/Fecundidad:1950–2100",
                 border="grey80")
legend("bottomright", c(paste("Proy:", 
                      c("A. Latina", "Brasil", "Colombia"))), cex=1,
        col=c("black","red", "blue"), lwd=2, bty="n",  
        lty=c(1,1,2), pch=c(NA,1,1) )
于 2015-07-29T00:42:06.653 回答
4

与@BenBolker 接受的答案类似的另一种选择是在添加第二组点时重新定义现有绘图的坐标。

这是一个最小的例子。

数据:

x  <- 1:10
y1 <- rnorm(10, 100, 20)
y2 <- rnorm(10, 1, 1)

阴谋:

par(mar=c(5,5,5,5)+0.1, las=1)

plot.new()
plot.window(xlim=range(x), ylim=range(y1))
points(x, y1, col="red", pch=19)
axis(1)
axis(2, col.axis="red")
box()

plot.window(xlim=range(x), ylim=range(y2))
points(x, y2, col="limegreen", pch=19)
axis(4, col.axis="limegreen")

title("my plot", adj=0)
mtext("2nd y axis", side = 4, las=3, line=3, col="limegreen")
mtext("1st y axis", side = 2, las=3, line=3, col="red")

例子

于 2018-10-08T12:15:54.047 回答