使用grid.curve连接不同视图中的grobs

4

R图形具有网格包,理论上允许使用grid.curve在形状之间创建曲线箭头(请参见此处的grid.curve描述https://www.stat.auckland.ac.nz/~paul/grid/curve/curve.pdf)。但是,似乎grid.curve无法连接跨视图的grobs。

我想将以下代码更改为使用曲线箭头连接两个圆圈,就像grid.curve函数示例一样。 有人知道如何做到这一点吗?

以下是示例代码

library(grid)
library(gridExtra)

# Layout Branches
pdf("test.pdf")
grid.newpage()
layout=grid.layout(nrow=2,ncol=2)
pushViewport(viewport(layout=layout,name="base"))

#Now add circles for states
seekViewport("base")
for (ii in 1:2) {
  for(jj in 1:2) {
   name=paste(ii,jj,sep="a")    
   name2=paste(ii,jj,sep="_")  
   pushViewport(viewport(layout.pos.col=jj, layout.pos.row=ii, name = name2)) 
   grid.circle(r=.4, name = name)       
   upViewport()
}}

seekViewport("1_1")
grid.move.to(grobX("1a1",0),grobY("1a1",0)) 
seekViewport("2_2")
grid.line.to(grobX("2a2",180),grobY("2a2",180))
dev.off()

enter image description here


1
我正在处理这个问题,想分享一个非常有用的SO链接,由@Sharpie(Charlie Sharpensteen)提供:https://dev59.com/WlTTa4cB1Zd3GeqPr2FD#5048617 - IRTFM
不是关于你问题的答案,但是我曾经想要在圆圈之间绘制曲线箭头,最终使用了 diagram 包(例如参见 the vignette)。 - Henrik
2
@BondedDust 不错的链接。像 @Sharpie 的回答一样,我下面的代码也使用了 current.transform(),这似乎是在不同视口坐标系之间进行转换的唯一(或至少是最简单的)方法。值得一提的是,这也是 gridgrid.locator() 中内部使用的方法;另外,可以参考 Paul Murrell 在 这个 R-help 线程 中的贡献,以进一步证明没有更好的方法。 - Josh O'Brien
不知道这样说是否格式不当,但感谢大家!非常感激。 - evolvedmicrobe
@evolvedmicrobe 当然可以!感谢您提出这样一个有趣、解释得很清楚的问题。我从中学到了很多。 - Josh O'Brien
1个回答

3
这应该可以解决问题:
## Your code
grid.newpage()
layout=grid.layout(nrow=2,ncol=2)
pushViewport(viewport(layout=layout,name="base"))
seekViewport("base")
for (ii in 1:2) {
  for(jj in 1:2) {
   name=paste(ii,jj,sep="a")
   name2=paste(ii,jj,sep="_")
   pushViewport(viewport(layout.pos.col=jj, layout.pos.row=ii, name = name2))
   grid.circle(r=.4, name = name)
   upViewport()
}}

## Define a function that returns the location of the specified
## grob-edge point, in terms of the npc coordinate system of the
## entire device
getDeviceNPC <- function(vpName, grobName, theta) {
    seekViewport(vpName)
    A <- grid.move.to(grobX(grobName, theta), grobY(grobName, theta))
    x <- convertWidth(A$x, unitTo="inches")
    y <- convertHeight(A$y, unitTo="inches")
    xy <- unit((c(x,y,1) %*% current.transform())[1:2], "inches")
    seekViewport("base")
    convertUnit(xy, unitTo="npc")
}

## Use it to extract locations of a couple of points
A <- getDeviceNPC(vpName="1_1", grobName="1a1", theta=0)
B <- getDeviceNPC(vpName="2_2", grobName="2a2", theta=180)

## Draw a curve between the points
grid.curve(A[1], A[2], B[1], B[2], gp=gpar(col="red"), arrow=arrow(),
           curvature=-1, inflect=TRUE)

enter image description here


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