使用 ggraph/ggplot2 在网络图中定位节点和边
Positioning nodes and edges in network graph using ggraph/ggplot2
我正在尝试使用 ggraph 绘制网络,我想在图形周围添加一个圆圈,边和节点位于圆圈的中心。
使用以下代码(改编自Draw a circle with ggplot2)绘制圆圈效果很好
gg_circle <- function(r, xc, yc, color = "black", fill = NA, lty = NA, size = NA, ...) {
x <- xc + r*cos(seq(0, pi, length.out = 100))
ymax <- yc + r*sin(seq(0, pi, length.out = 100))
ymin <- yc + r*sin(seq(0, -pi, length.out = 100))
annotate("ribbon", x = x, ymin = ymin, ymax = ymax,
color = color, fill = fill, lty = lty, size = size, ...)
}
但我无法将网络层的位置与圆的位置相匹配,这导致节点和边都部分位于圆的外部:
这是代码的关键部分,因为它现在是(使用 ggraph
中的 highschool
作为示例数据集以实现重现性目的):
library(ggraph)
library(igraph)
graph <- graph_from_data_frame(highschool)
ggraph(graph, layout = "fr") +
geom_edge_link() +
geom_node_point() +
geom_node_text(aes(label = name),
check_overlap = TRUE, repel = TRUE,
nudge_x = 0.1, nudge_y = 0.1) +
gg_circle(r = 11, xc = 0, yc = 0, lty = 1, size = 0.2) +
theme(axis.ticks.length = unit(0, "cm"),
legend.position = "none",
plot.margin = unit(c(0, 0, 0, 0), "cm"),
panel.spacing = unit(c(0, 0, 0, 0), "cm")) +
coord_fixed()
关于如何解决这个问题有什么想法或建议吗?提前致谢!
我会尝试使用节点位置来找到 r
、xc
和 yc
的可接受值。
步骤 1。创建绘图(不带圆圈):
set.seed(9) # for reproducibility
p <- ggraph(graph, layout = "fr") +
geom_edge_link() +
geom_node_point() +
geom_node_text(aes(label = name),
check_overlap = TRUE,
repel = TRUE,
nudge_x = 0.1,
nudge_y = 0.1) +
theme(axis.ticks.length = unit(0, "cm"),
legend.position = "none",
plot.margin = unit(c(0, 0, 0, 0), "cm"),
panel.spacing = unit(c(0, 0, 0, 0), "cm")) +
coord_fixed()
步骤 2。从绘图的 geom_node_point()
层(在本例中为第 2 层)获取数据。修改 gg_circle code
以将此数据框作为输入,并计算适当的圆心坐标/半径:
p.positions <- layer_data(p, i = 2L)
gg_circle_from_position <- function(data,
color = "black", fill = NA,
lty = NA, size = NA, ...){
coord.x <- data[, 'x']
coord.y <- data[, 'y']
xc = mean(range(coord.x))
yc = mean(range(coord.y))
r = max(sqrt((coord.x - xc)^2 + (coord.y - yc)^2)) * 1.05
# expand radius by 5% so that no node sits exactly on the line;
# increase from 1.05 to some larger number if more buffer is desired.
# no change to this part
x <- xc + r*cos(seq(0, pi, length.out = 100))
ymax <- yc + r*sin(seq(0, pi, length.out = 100))
ymin <- yc + r*sin(seq(0, -pi, length.out = 100))
annotate("ribbon", x = x, ymin = ymin, ymax = ymax,
color = color, fill = fill, lty = lty, size = size, ...)
}
步骤 3。向绘图添加圆圈:
p + gg_circle_from_position(data = p.positions, lty = 1, size = 0.2)
我正在尝试使用 ggraph 绘制网络,我想在图形周围添加一个圆圈,边和节点位于圆圈的中心。
使用以下代码(改编自Draw a circle with ggplot2)绘制圆圈效果很好
gg_circle <- function(r, xc, yc, color = "black", fill = NA, lty = NA, size = NA, ...) {
x <- xc + r*cos(seq(0, pi, length.out = 100))
ymax <- yc + r*sin(seq(0, pi, length.out = 100))
ymin <- yc + r*sin(seq(0, -pi, length.out = 100))
annotate("ribbon", x = x, ymin = ymin, ymax = ymax,
color = color, fill = fill, lty = lty, size = size, ...)
}
但我无法将网络层的位置与圆的位置相匹配,这导致节点和边都部分位于圆的外部:
这是代码的关键部分,因为它现在是(使用 ggraph
中的 highschool
作为示例数据集以实现重现性目的):
library(ggraph)
library(igraph)
graph <- graph_from_data_frame(highschool)
ggraph(graph, layout = "fr") +
geom_edge_link() +
geom_node_point() +
geom_node_text(aes(label = name),
check_overlap = TRUE, repel = TRUE,
nudge_x = 0.1, nudge_y = 0.1) +
gg_circle(r = 11, xc = 0, yc = 0, lty = 1, size = 0.2) +
theme(axis.ticks.length = unit(0, "cm"),
legend.position = "none",
plot.margin = unit(c(0, 0, 0, 0), "cm"),
panel.spacing = unit(c(0, 0, 0, 0), "cm")) +
coord_fixed()
关于如何解决这个问题有什么想法或建议吗?提前致谢!
我会尝试使用节点位置来找到 r
、xc
和 yc
的可接受值。
步骤 1。创建绘图(不带圆圈):
set.seed(9) # for reproducibility
p <- ggraph(graph, layout = "fr") +
geom_edge_link() +
geom_node_point() +
geom_node_text(aes(label = name),
check_overlap = TRUE,
repel = TRUE,
nudge_x = 0.1,
nudge_y = 0.1) +
theme(axis.ticks.length = unit(0, "cm"),
legend.position = "none",
plot.margin = unit(c(0, 0, 0, 0), "cm"),
panel.spacing = unit(c(0, 0, 0, 0), "cm")) +
coord_fixed()
步骤 2。从绘图的 geom_node_point()
层(在本例中为第 2 层)获取数据。修改 gg_circle code
以将此数据框作为输入,并计算适当的圆心坐标/半径:
p.positions <- layer_data(p, i = 2L)
gg_circle_from_position <- function(data,
color = "black", fill = NA,
lty = NA, size = NA, ...){
coord.x <- data[, 'x']
coord.y <- data[, 'y']
xc = mean(range(coord.x))
yc = mean(range(coord.y))
r = max(sqrt((coord.x - xc)^2 + (coord.y - yc)^2)) * 1.05
# expand radius by 5% so that no node sits exactly on the line;
# increase from 1.05 to some larger number if more buffer is desired.
# no change to this part
x <- xc + r*cos(seq(0, pi, length.out = 100))
ymax <- yc + r*sin(seq(0, pi, length.out = 100))
ymin <- yc + r*sin(seq(0, -pi, length.out = 100))
annotate("ribbon", x = x, ymin = ymin, ymax = ymax,
color = color, fill = fill, lty = lty, size = size, ...)
}
步骤 3。向绘图添加圆圈:
p + gg_circle_from_position(data = p.positions, lty = 1, size = 0.2)