networkx - 选择考虑边缘标签的 networkx 布局
问题描述
我正在使用draw_networkx_edge_labels函数绘制 networkx 加权图。我的问题是,由于边缘有时会相互交叉,因此从图中并不总是清楚哪个权重属于哪个边缘。例如,在下图中,不清楚 2 是 (1,2) 还是 (3,7) 的权重。
我目前正在使用neato 布局,它不考虑边缘标签。特别是,这就是我绘制加权图的方式g
:
layout = nx.nx_pydot.graphviz_layout(g, prog='neato')
nx.draw(g, pos=layout)
edge_labels = nx.get_edge_attributes(g, 'weight')
nx.draw_networkx_edge_labels(g, pos=layout, edge_labels=edge_labels)
我知道我可以使用参数手动控制标签沿边缘的位置label_pos
,但我的问题是是否存在一种自动绘制图形的方法,这样边缘标签通常不会发生碰撞(或者使用考虑标签的布局或“整齐地”选择沿边缘的标签位置的方法)。
我并不期待总是有效的东西,但由于我的图表连接相对稀疏,我希望有一种方法至少可以很好地工作。
解决方案
一段时间以来,我一直打算在netgraph中实现这一点,我的 networkx 绘图实用程序的分支。不幸的是,我星期四有一个工作面试,所以我很快就没有时间写这个了。然而,基本思想非常简单,并且已经在一些 R 包中实现,例如ggrepel
和ggnetwork
.
基本思想是,在给定节点和边缘的预定和固定布局的情况下,您使用强制导向布局来定位标签。所以:
使用您选择的布局计算节点布局。
将每条边划分为许多节点的链,并使用边的源节点和目标节点的已知位置计算“边节点”的位置。这种划分是为了在下面的力导向布局中给每条边一个“质量”。
对于每条边,添加一个“标签”节点并将其连接到最中心的“边节点”。
计算一个力导向布局,保持除标签节点之外的所有节点固定(例如
spring_layout
在networkx中使用)。
您现在应该有不与任何边缘重叠的合理边缘标签坐标。用于plt.annotate
绘制边缘和边缘标签之间的连接。
推荐阅读
- algorithm - 为什么我们应该在 GP 求和公式中使用模乘逆?
- opencv - Kinect2 的对象检测 API“无法处理此数据类型”错误
- python - 如何解决“安装 steem-python 时出错”
- powershell - 如何为 CSV 文件中的每一行导入前两个值 | 电源外壳
- anaconda - 在 Anaconda 上安装 Miniconda?
- reactjs - 将组件和道具作为参数传递
- javascript - Botpress 错误:没有这样的表:web_conversations
- powershell - 通过 PowerShell 重新启动服务并检查远程服务器上的状态
- c# - 我是否过于复杂了?(CQRS、领域事件和命令失败)
- knockout.js - 如何有条件地绑定到 knockout.js 中的“valueUpdate”?