【问题标题】:Automatically curving an arc when it is overlapping with another one当弧与另一弧重叠时自动弯曲弧
【发布时间】:2018-01-25 01:59:58
【问题描述】:

我正在自动生成其节点需要位于固定位置的图形。例如:

实际上有一条从节点V4到节点V16的弧,但是我们没有看到它,因为也有从V4到V10和从V10到V16的弧。

请注意,节点和弧都是自动生成的,并且位置可能会有所不同,因此我需要一种自动方法来弯曲隐藏在其他弧后面的弧。


另请注意,这些解决方案均无效:igraph: Resolving tight overlapping nodesUsing igraph, how to force curvature when arrows point in opposite directions。第一个只是以某种方式放置de节点,但我的节点需要固定。第二个简单地处理一对节点,这些节点有两条弧线连接它们,方向相反。


更新:图的构造是使用 bnlearn 库形成Bayesian Network 的图的学习过程的结果,所以我不太确定如何生成可重现的示例。节点的位置是固定的,因为它们代表位置。我实际上需要一些魔法,某种重叠弧的检测:如果两条弧重叠,稍微弯曲其中一个,以便可以看到它。我从链接的问题中知道弯曲弧线是一种选择,所以我想也许可以实现这种魔法

【问题讨论】:

  • 如果您提供带有示例输入数据的reproducible example,这样我们就可以运行和测试代码,这样会更容易提供帮助。还要清楚地描述所需的输出。你到底想在最终情节中发生什么(不仅仅是“魔法”)?
  • @MrFlick 图的构建实际上是使用 bnlearn 形成 Bayesian Network 的图的学习过程的结果,所以我不太确定如何生成可重现的示例。节点的位置是固定的,因为它们代表位置。我实际上需要一些魔法,某种重叠弧的检测:如果两条弧重叠,稍微弯曲其中一个,以便可以看到它。我从链接的问题中知道弯曲弧线是一种选择,所以我认为也许可以实现这种魔法。
  • 我们不需要来自 bnlearn 的数据,只需要图表:例如as.data.frame(get.edgelist(gr)) 和创建重叠边缘的布局。
  • @emilliman5,我不明白你的意思,节点和边都不总是相同的
  • 如果你没有在 igraph 上设置.. 你可以使用 graphviz 来做到这一点(你可能在 bnlearn 加载它时拥有它)。通过一些文本操作,您可以使用neato 设置位置和渲染,(我认为(会弯曲边缘。

标签: r igraph


【解决方案1】:

一种解决方案是使用qgraph 包。在下面的示例中,它会自动弯曲双向边缘:

library(igraph)
library(qgraph)

# the raster layout
layout <- cbind(1:3, rep(1:3, each = 3))
# fully connected network
adj <- matrix(1, 9, 9)

# plot directed and undirected network
layout(matrix(1:2, 1, 2))
qgraph(adj, layout = layout, directed = FALSE, title = "undirected")
qgraph(adj, layout = layout, directed = TRUE, title = "directed") # automatically curves the bidirectional arrows

要将igraph 对象转换为 qgraph 可以使用的对象,您只需要一个边列表或邻接矩阵:

g <- make_ring(9)
edgeList <- do.call(rbind, igraph::get.adjedgelist(g))
qgraph(edgeList)

如果您还想包含坐标轴,您可以使用axis() 这样做,因为 qgraph 使用基本图形。但是,您可能还需要修改 par() 以使其看起来不错。

【讨论】:

  • 这很酷,但是如果边缘不是双向的,有没有一种简单的方法可以使边缘弯曲。例如,使用 adj 矩阵 adj[lower.tri(adj, diag=TRUE)] &lt;- 0我认为代表了操作的用例 - 看不到从 1 到 7 的边
  • 有,使用参数curveAlladj &lt;- matrix(0, 9, 9); adj[cbind(1, 2:3)] &lt;- 1; adj[cbind(2:3, 1)] &lt;- 1; qgraph(adj, layout = layout, curveAll = -1)。使用参数edge.colorarrows 的不同方法也存在,但有点hacky。
  • 感谢 Vanderman,这给出了与使用 igraph 的 edge.curved 相似的结果。最好只弯曲未弯曲的 隐藏 边缘并保持其他边缘笔直,但我想识别这些边缘并非易事。(即 1 到 4 和 4 到 7直的,但有 1 到 7 个弯曲)
  • 啊没听懂,抱歉。如果你有一个边列表并且布局是相邻节点之间的距离为 1,你不能只弯曲长度 > 1 的所有边吗?通过其他节点下方的边缘也可能会令人困惑。
  • 我想过做类似that 的事情,但另一个困难是,并非所有距离> 1 的边都需要弯曲——也就是说,您仍然希望边1 到8 是直的。可能是一些花哨的图搜索算法,但是??? (只是希望你能有一些灵感;))
猜你喜欢
  • 1970-01-01
  • 2014-03-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多