如何用2个不同的y轴绘图?

时间:2011-05-26 17:53:13

标签: r plot yaxis

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

是否可以使用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)

6 个答案:

答案 0 :(得分:104)

更新:复制的材料位于R维基上的http://rwiki.sciviews.org/doku.php?id=tips:graphics-base:2yaxes,现在链接已损坏:也可从the wayback machine

获取

同一图中的两个不同的y轴

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

请注意,在同一地块上使用两个不同比例的情况很少。误导图形的观察者很容易。请查看以下两个示例和对此问题的评论(example1example2中的Junk Charts)以及this article by Stephen Few(其结论是“我当然不能得出结论,一次和所有,具有双刻度轴的图形永远不会有用;只是我不能想到根据其他更好的解决方案保证它们的情况。“)另见this cartoon中的第4点...

如果您确定,基本配方是创建第一个图,设置par(new=TRUE)以防止R清除图形设备,使用axes=FALSE创建第二个图(并设置xlab }和ylab为空白 - ann=FALSE也应该有效),然后使用axis(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"))

enter image description here

类似的配方可以用来叠加不同类型的图 - 条形图,直方图等。

答案 1 :(得分:33)

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

library(plotrix)
example(twoord.plot)

enter image description here

enter image description here

enter image description here

enter image description here

enter image description here

答案 2 :(得分:5)

一种选择是并排制作两个地块。 ggplot2facet_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")

答案 3 :(得分:3)

如果您可以放弃比例/轴标签,则可以将数据重新缩放到(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
}

然后,如果数据框包含chrompositioncoveragefst列,您可以执行以下操作:

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

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

答案 4 :(得分:2)

I too suggests, class Cart < ActiveRecord::Base has_many :line_items, dependent: :destroy in the twoord.stackplot() package plots with more of two ordinate axes.

plotrix

答案 5 :(得分:0)

另一种类似于@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")

example