你如何在R中的多图形环境中画一条线?

时间:2012-04-02 23:02:32

标签: r graph

举一个非常简单的例子,mfrow=c(1,3);每个图都是不同的直方图;如何画出一条横跨所有 3个数字的水平线(类似于abline(h=10))? (即使是它们之间的边距。)显然,我可以为每个数字添加一个基线,但这不是我想要的。我可以想到一个非常复杂的方法来做到这一点真的只有1个数字,并使用polygon等在其中绘制每个'数字'。这将是荒谬的。有没有一种简单的方法可以做到这一点?

3 个答案:

答案 0 :(得分:15)

正如@joran所说,网格图形系统可以更灵活地控制单个设备上多个图的排列。

在这里,我首先使用grconvertY()以"标准化设备坐标"为单位查询y轴上50的高度位置。 (即,作为绘图设备总高度的一部分,0 =底部,1 =顶部)。然后我使用网格功能:(1)推送填充设备的viewport; (2)在grconvertY()返回的高度绘制一条线。

## Create three example plots
par(mfrow=c(1,3))
barplot(VADeaths, border = "dark blue") 
barplot(VADeaths, border = "yellow") 
barplot(VADeaths, border = "green") 

## From third plot, get the "normalized device coordinates" of 
## a point at a height of 50 on the y-axis.
(Y <- grconvertY(50, "user", "ndc"))
# [1] 0.314248

## Add the horizontal line using grid
library(grid)
pushViewport(viewport())
grid.lines(x = c(0,1), y = Y, gp = gpar(col = "red"))
popViewport()

enter image description here

编辑:@joran询问如何绘制从第1个绘图的y轴延伸到第3个绘图中最后一个条的边缘的直线。以下是几种选择:

library(grid)
library(gridBase)
par(mfrow=c(1,3))

# barplot #1
barplot(VADeaths, border = "dark blue") 
X1 <- grconvertX(0, "user", "ndc")
# barplot #2
barplot(VADeaths, border = "yellow") 
# barplot #3
m <- barplot(VADeaths, border = "green") 
X2 <- grconvertX(tail(m, 1) + 0.5, "user", "ndc") # default width of bars = 1
Y <- grconvertY(50, "user", "ndc")

## Horizontal line
pushViewport(viewport())
grid.lines(x = c(X1, X2), y = Y, gp = gpar(col = "red"))
popViewport()

enter image description here

最后,这里有一个几乎等效的,更普遍有用的方法。它使用了Paul Murrell在@ mdsumner答案中链接的文章中的grid.move.to()grid.line.to()演示函数:

library(grid)
library(gridBase)
par(mfrow=c(1,3))

barplot(VADeaths); vps1 <- do.call(vpStack, baseViewports())
barplot(VADeaths) 
barplot(VADeaths); vps3 <- do.call(vpStack, baseViewports())

pushViewport(vps1)
Y <- convertY(unit(50,"native"), "npc")
popViewport(3)

grid.move.to(x = unit(0, "npc"), y = Y, vp = vps1)
grid.line.to(x = unit(1, "npc"), y = Y, vp = vps3, 
             gp = gpar(col = "red"))

答案 1 :(得分:6)

这是我能做的最好的事情,而不用考虑更难:

par(mfrow = c(1,3),xpd = NA)

for (i in 1:3){
    x <- rnorm(200,i)
    hist(x)
    if (i == 1) segments(par("usr")[1],10,30,10)
}

enter image description here

我不确定如何在没有修补的情况下确保线路在正确的位置结束。绘制每个区域中的一个区段可以解决这个问题,但是会引入高度排列正确的问题。但这可能是一个很好的起点,至少。

我猜这在网格图形中更容易,但我必须做一些研究来验证。

答案 2 :(得分:4)

Paul Murrell的这篇文章展示了使用grid图形在两个不同的坐标系之间绘制线条,在这种情况下,在两个独立的子图的原生空间中指定了端点的线:

Paul Murrell。网格图形包。 R News,2(2):14-19,2002年6月

这是PDF文章的第17页:

http://cran.r-project.org/doc/Rnews/Rnews_2002-2.pdf