我想在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)
答案 0 :(得分:104)
更新:复制的材料位于R维基上的http://rwiki.sciviews.org/doku.php?id=tips:graphics-base:2yaxes,现在链接已损坏:也可从the wayback machine
获取(一些材料最初由Daniel Rajdl 2006/03/31 15:26发表)
请注意,在同一地块上使用两个不同比例的情况很少。误导图形的观察者很容易。请查看以下两个示例和对此问题的评论(example1,example2中的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"))
类似的配方可以用来叠加不同类型的图 - 条形图,直方图等。
答案 1 :(得分:33)
答案 2 :(得分: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")
答案 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
}
然后,如果数据框包含chrom
,position
,coverage
和fst
列,您可以执行以下操作:
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")