手动绘制图形
Drawing manually on a figure
我生成了一个图表:
library(DiagrammeR)
grViz("
digraph boxes_and_circles {
# a 'graph' statement
graph [layout = neato, overlap = true, fontsize = 10, outputorder = edgesfirst]
# several 'node' statements
node [shape = circle,
fontname = Helvetica]
A [pos = '1,1!'];
B [pos = '0,2!'];
C [pos = '1.5,3!'];
D [pos = '2.5,1!'];
E [pos = '4,1!'];
F [pos = '4,2!'];
G [pos = '5,1!'];
H [pos = '6,2!'];
I [pos = '1.5,-0.1!'];
# several 'edge' statements
A->B B->C
D->E D->F E->F E->G F->G G->H F->H
}
")
产生:
现在我想用虚线围绕节点 A、B 和 C 绘制一个框。
我如何在 R 中完成此操作?该解决方案的一个关键要求是它是可重现的,即我可以多次 运行 脚本并获得相同的结果。
您可以为小部件使用@StevenBeaupre 的解决方案,但是有一些包使用 R 的图形绘制网络。如果您愿意使用其他解决方案,一种是 igraph
。
这将使图表
library('igraph')
set.seed(11)
g <- data.frame(from = c('A', 'B', 'I', 'D', 'D', 'E', 'E', 'F', 'F', 'G'),
to = c('B', 'C', 'I', 'E', 'F', 'G', 'F', 'H', 'G', 'H'))
(gg <- graph.data.frame(g, directed = TRUE))
plot(gg, vertex.color = 'white')
并且有很多方法可以将方框添加到 r 图形中;这是一个您可以单击绘图添加框而无需计算任何东西的地方
rekt <- function(...) {
coords <- c(unlist(locator(1)), unlist(locator(1)))
rect(coords[1], coords[2], coords[3], coords[4], ..., xpd = NA)
}
rekt(border = 'red', lty = 'dotted', lwd = 2)
我明白了
这是另一种基于 igraph 的方法。它的灵感来自这个 igraph code sample.
我假设使用 igraph 而不是 DiagrammeR 是一种选择 - 也许事实并非如此......
我们将顶点的定位留给标准布局算法,并向其查询生成的顶点位置。然后使用这些位置在任意一组 "selected" 顶点周围绘制一个虚线矩形。不需要用户交互。
我们从图形拓扑开始。
library(igraph)
set.seed(42)
df <- data.frame(from = c('A', 'B', 'I', 'D', 'D', 'E', 'E', 'F', 'F', 'G'),
to = c('B', 'C', 'I', 'E', 'F', 'G', 'F', 'H', 'G', 'H'))
g <- graph.data.frame(df, directed = TRUE)
图中顶点和箭头的大小可以根据喜好自由设置。
vertexsize <- 50
arrowsize <- 0.2
我们要求 Fruchterman-Reingold 布局引擎计算顶点的坐标。
coords <- layout_with_fr(g)
然后绘制图表。
plot(g,
layout = coords,
vertex.size = vertexsize,
edge.arrow.size = arrowsize,
rescale = FALSE,
xlim = range(coords[,1]),
ylim = range(coords[,2]))
如果我们想看看发生了什么,我们可以添加坐标轴并打印顶点坐标:
axis(1)
axis(2)
V(g) # ordered vertex list
coords # coordinates of the vertices (in the same coordinate system as our dotted rectangle)
我们现在找出我们想要矩形围绕的顶点的边界框。
selectedVertices = c("A", "B", "C")
vertexIndices <- sapply(selectedVertices, FUN = function(x) { return(as.numeric(V(g)[x])) } )
llx <- min(coords[vertexIndices, 1])
lly <- min(coords[vertexIndices, 2])
urx <- max(coords[vertexIndices, 1])
ury <- max(coords[vertexIndices, 2])
快到了。我们在coords[]中已经有了顶点centers的坐标,但是我们还需要plot坐标系中顶点的size( ).从 plot.igraph 源代码我们可以看到 plot() 的 vertex.size 选项除以 200,然后用作绘制顶点的半径。绘制虚线矩形时,我们使用大 50% 的值作为顶点坐标边界框周围的边距。
margin <- (vertexsize / 200) * 1.5
rect(llx - margin, lly - margin, urx + margin, ury + margin, lty = 'dotted')
这是我们得到的结果:
DiagrammR
的一个简单解决方案是使用点而不是 neato。您基本上失去了手动定位节点的能力(属性 pos 不再起作用),但您获得了使用集群和子图在节点集周围画线的能力。
library(DiagrammeR)
grViz("
digraph boxes_and_circles {
# a 'graph' statement
graph [ fontsize = 10,rankdir=LR]
# several 'node' statements
node [shape = circle,
fontname = Helvetica]
# several 'edge' statements
subgraph cluster_1 {
style=dotted
A->B->C
}
D->E D->F E->F E->G F->G G->H F->H
I
}
")
我生成了一个图表:
library(DiagrammeR)
grViz("
digraph boxes_and_circles {
# a 'graph' statement
graph [layout = neato, overlap = true, fontsize = 10, outputorder = edgesfirst]
# several 'node' statements
node [shape = circle,
fontname = Helvetica]
A [pos = '1,1!'];
B [pos = '0,2!'];
C [pos = '1.5,3!'];
D [pos = '2.5,1!'];
E [pos = '4,1!'];
F [pos = '4,2!'];
G [pos = '5,1!'];
H [pos = '6,2!'];
I [pos = '1.5,-0.1!'];
# several 'edge' statements
A->B B->C
D->E D->F E->F E->G F->G G->H F->H
}
")
产生:
现在我想用虚线围绕节点 A、B 和 C 绘制一个框。
我如何在 R 中完成此操作?该解决方案的一个关键要求是它是可重现的,即我可以多次 运行 脚本并获得相同的结果。
您可以为小部件使用@StevenBeaupre 的解决方案,但是有一些包使用 R 的图形绘制网络。如果您愿意使用其他解决方案,一种是 igraph
。
这将使图表
library('igraph')
set.seed(11)
g <- data.frame(from = c('A', 'B', 'I', 'D', 'D', 'E', 'E', 'F', 'F', 'G'),
to = c('B', 'C', 'I', 'E', 'F', 'G', 'F', 'H', 'G', 'H'))
(gg <- graph.data.frame(g, directed = TRUE))
plot(gg, vertex.color = 'white')
并且有很多方法可以将方框添加到 r 图形中;这是一个您可以单击绘图添加框而无需计算任何东西的地方
rekt <- function(...) {
coords <- c(unlist(locator(1)), unlist(locator(1)))
rect(coords[1], coords[2], coords[3], coords[4], ..., xpd = NA)
}
rekt(border = 'red', lty = 'dotted', lwd = 2)
我明白了
这是另一种基于 igraph 的方法。它的灵感来自这个 igraph code sample.
我假设使用 igraph 而不是 DiagrammeR 是一种选择 - 也许事实并非如此......
我们将顶点的定位留给标准布局算法,并向其查询生成的顶点位置。然后使用这些位置在任意一组 "selected" 顶点周围绘制一个虚线矩形。不需要用户交互。
我们从图形拓扑开始。
library(igraph)
set.seed(42)
df <- data.frame(from = c('A', 'B', 'I', 'D', 'D', 'E', 'E', 'F', 'F', 'G'),
to = c('B', 'C', 'I', 'E', 'F', 'G', 'F', 'H', 'G', 'H'))
g <- graph.data.frame(df, directed = TRUE)
图中顶点和箭头的大小可以根据喜好自由设置。
vertexsize <- 50
arrowsize <- 0.2
我们要求 Fruchterman-Reingold 布局引擎计算顶点的坐标。
coords <- layout_with_fr(g)
然后绘制图表。
plot(g,
layout = coords,
vertex.size = vertexsize,
edge.arrow.size = arrowsize,
rescale = FALSE,
xlim = range(coords[,1]),
ylim = range(coords[,2]))
如果我们想看看发生了什么,我们可以添加坐标轴并打印顶点坐标:
axis(1)
axis(2)
V(g) # ordered vertex list
coords # coordinates of the vertices (in the same coordinate system as our dotted rectangle)
我们现在找出我们想要矩形围绕的顶点的边界框。
selectedVertices = c("A", "B", "C")
vertexIndices <- sapply(selectedVertices, FUN = function(x) { return(as.numeric(V(g)[x])) } )
llx <- min(coords[vertexIndices, 1])
lly <- min(coords[vertexIndices, 2])
urx <- max(coords[vertexIndices, 1])
ury <- max(coords[vertexIndices, 2])
快到了。我们在coords[]中已经有了顶点centers的坐标,但是我们还需要plot坐标系中顶点的size( ).从 plot.igraph 源代码我们可以看到 plot() 的 vertex.size 选项除以 200,然后用作绘制顶点的半径。绘制虚线矩形时,我们使用大 50% 的值作为顶点坐标边界框周围的边距。
margin <- (vertexsize / 200) * 1.5
rect(llx - margin, lly - margin, urx + margin, ury + margin, lty = 'dotted')
这是我们得到的结果:
DiagrammR
的一个简单解决方案是使用点而不是 neato。您基本上失去了手动定位节点的能力(属性 pos 不再起作用),但您获得了使用集群和子图在节点集周围画线的能力。
library(DiagrammeR)
grViz("
digraph boxes_and_circles {
# a 'graph' statement
graph [ fontsize = 10,rankdir=LR]
# several 'node' statements
node [shape = circle,
fontname = Helvetica]
# several 'edge' statements
subgraph cluster_1 {
style=dotted
A->B->C
}
D->E D->F E->F E->G F->G G->H F->H
I
}
")