[英]R network plot with node types fixed in columns
我有两个看起来像这样的数据框:
y1 <- c(1, 0, 0)
y2 <- c(0, 1, 0)
y3 <- c(0, 0, 1)
df1 <- data.frame(y1, y2, y3, row.names = c("x1", "x2", "x3"))
y1 <- c(1, 0, 0)
y2 <- c(1, 0, 0)
y3 <- c(1, 0, 0)
df2 <- data.frame(y1, y2, y3, row.names = c("z1", "z2", "z3"))
我想在这些数据框中绘制关系图,以便x,y和z值出现在带有连接它们的线的列中。 这是我要实现的目标的粗略示例:
我考虑过使用带有在X轴上的分类变量的ggplot2散点图来生成列,但是我不知道如何从中生成点之间的连接线。 我还查看了ggnet2的网络图,但是找不到任何将节点固定在列中的示例。
编辑:
我的实际用例大约有20 x点,120 y点和200 z点,因此理想情况下该解决方案可以轻松扩展。
我尝试使用networkD3软件包中的sankeynetwork图进行以下解决方案
library(networkD3)
Nodes <- data.frame(name = c("x1", "x2", "x3", "y1", "y2", "y3", "z1",
"z2", "z3"), group = c("1", "1", "1", "2", "2", "2", "3", "3",
"3"))
Links <- data.frame(source = c(0, 1, 2, 3, 4, 5), target = c(3, 4, 5, 6,
6, 6), value = 1, 1, 1, 1, 1, 1)
sankeyNetwork(Links = Links, Nodes = Nodes, Source = "source",
Target = "target", Value = "value", NodeGroup = "group", NodeID
= "name", sinksRight = FALSE)
结果是正确的……但是它可能并不理想。 另外,似乎没有一种明确的方法可以强制z2和z3与z1一起显示在页面的右侧,而无需进入底层的javascript,我不知道该怎么做(请参阅d3 sankey图表-手动定位沿x轴的节点 )
是否有更好的解决方案或改进此方法的方法?
谢谢!
这是使用geom_segment
绘制连接边的一种可能的解决方案。 我不适应比您的示例更大或更复杂的数据集。 我怀疑使用igraph
或ggraph
有更优雅,更可扩展的方式来处理此ggraph
。
# Start with two data.frames: one for node positions,
# and one for edges you want to draw between nodes.
pos_dat = data.frame(node_id=paste(rep(c("x", "y", "z"), each=3),
rep(c("1", "2", "3"), times=3),
sep=""),
type=rep(c("x", "y", "z"), each=3),
xpos=rep(c(1, 2, 3), each=3),
ypos=rep(c(1, 2, 3), times=3))
# node_id type xpos ypos
# 1 x1 x 1 1
# 2 x2 x 1 2
# 3 x3 x 1 3
# 4 y1 y 2 1
# 5 y2 y 2 2
# 6 y3 y 2 3
# 7 z1 z 3 1
# 8 z2 z 3 2
# 9 z3 z 3 3
edge_dat = data.frame(start=c("x1", "x2", "x3", "y1", "y2", "y3"),
end=c("y1", "y2", "y3", "z1", "z1", "z1"))
# start end
# 1 x1 y1
# 2 x2 y2
# 3 x3 y3
# 4 y1 z1
# 5 y2 z1
# 6 y3 z1
# Use two successive merges to join node x,y positions
# for each edge you want to draw.
tmp_dat = merge(edge_dat, pos_dat, by.x="start", by.y="node_id")
seg_dat = merge(tmp_dat, pos_dat, by.x="end", by.y="node_id")
# Remove unneeded columns and change column names for convenience.
seg_dat$type.x = NULL
seg_dat$type.y = NULL
names(seg_dat) = c("end", "start", "x", "y", "xend", "yend")
seg_dat
# end start x y xend yend
# 1 y1 x1 1 1 2 1
# 2 y2 x2 1 2 2 2
# 3 y3 x3 1 3 2 3
# 4 z1 y1 2 1 3 1
# 5 z1 y2 2 2 3 1
# 6 z1 y3 2 3 3 1
# Finally, draw the plot.
library(ggplot2)
p = ggplot() +
geom_segment(data=seg_dat, aes(x=x, y=y, xend=xend, yend=yend),
colour="grey50") +
geom_point(data=pos_dat, aes(x=xpos, y=ypos, colour=type), size=10) +
geom_text(data=pos_dat, aes(x=xpos, y=ypos, label=node_id)) +
scale_colour_manual(values=c(x="steelblue", y="darkorange", z="olivedrab3"))
ggsave("plot.png", plot=p, height=4, width=6, dpi=150)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.