【发布时间】:2017-02-09 15:26:36
【问题描述】:
我正在尝试使用Python(最好使用matplotlib 和networkx,尽管对bokeh 感兴趣)创建一个线性网络图,其概念类似于下面的。
如何在 Python 中使用 networkx 有效地构造此图表(pos?)? 我想将其用于更复杂的示例,因此我觉得为此很难对位置进行编码简单的例子不会有用:(。networkx 有解决方案吗?
我在networkx 中没有看到任何关于如何实现这一点的教程,这就是为什么我相信这个问题将成为社区的可靠资源。我已经广泛地浏览了networkx tutorials,但那里没有这样的东西。如果不仔细使用 pos 参数,networkx 的布局将使这种类型的网络无法解释......我相信这是我唯一的选择。 https://networkx.github.io/documentation/networkx-1.9/reference/drawing.html 文档中的预计算布局似乎都不能很好地处理这种类型的网络结构。
简单示例:
(A) 每个外键是图中从左向右移动的迭代(例如,迭代 0 表示样本,迭代 1 具有组 1-3,与迭代 2 相同,迭代 3 具有组 1-2,等等.)。 (B) 内部字典包含该特定迭代中的当前分组,以及表示当前组的先前组合并的权重(例如,iteration 3 具有 Group 1 和 Group 2 以及 iteration 4 的所有 @987654346 @Group 2 已进入 iteration 4's Group 2 但 iteration 3's Group 1 已拆分。权重总和为 1。
我的连接代码与上图的权重:
D_iter_current_previous = {
1: {
"Group 1":{"sample_0":0.5, "sample_1":0.5, "sample_2":0, "sample_3":0, "sample_4":0},
"Group 2":{"sample_0":0, "sample_1":0, "sample_2":1, "sample_3":0, "sample_4":0},
"Group 3":{"sample_0":0, "sample_1":0, "sample_2":0, "sample_3":0.5, "sample_4":0.5}
},
2: {
"Group 1":{"Group 1":1, "Group 2":0, "Group 3":0},
"Group 2":{"Group 1":0, "Group 2":1, "Group 3":0},
"Group 3":{"Group 1":0, "Group 2":0, "Group 3":1}
},
3: {
"Group 1":{"Group 1":0.25, "Group 2":0, "Group 3":0.75},
"Group 2":{"Group 1":0.25, "Group 2":0.75, "Group 3":0}
},
4: {
"Group 1":{"Group 1":1, "Group 2":0},
"Group 2":{"Group 1":0.25, "Group 2":0.75}
}
}
这是我在networkx制作图表时发生的事情:
import networkx
import matplotlib.pyplot as plt
# Create Directed Graph
G = nx.DiGraph()
# Iterate through all connections
for iter_n, D_current_previous in D_iter_current_previous.items():
for current_group, D_previous_weights in D_current_previous.items():
for previous_group, weight in D_previous_weights.items():
if weight > 0:
# Define connections using `|__|` as a delimiter for the names
previous_node = "%d|__|%s"%(iter_n - 1, previous_group)
current_node = "%d|__|%s"%(iter_n, current_group)
connection = (previous_node, current_node)
G.add_edge(*connection, weight=weight)
# Draw Graph with labels and width thickness
nx.draw(G, with_labels=True, width=[G[u][v]['weight'] for u,v in G.edges()])
注意:我能想到的唯一其他方法是在matplotlib 创建一个散点图,每个刻度代表一次迭代(5 个包括初始样本),然后用不同的权重将这些点相互连接.这将是一些非常混乱的代码,特别是试图将标记的边缘与连接对齐......但是,我不确定这和 networkx 是否是最好的方法或者是否有一个工具(例如bokeh 或plotly)专为此类绘图而设计。
【问题讨论】:
-
你看过networkx tutorial吗? Plotting networkx graphs 在 matplotlib 中非常简单。您在什么时候遇到问题?
-
我知道如何使用networkx,但布局会使它们变得一团糟。我可以使用 pos 参数,但自定义位置字典很奇怪。我认为没有关于线性网络的教程
-
我认为有一种方法可以通过使用 graphviz 布局来做到这一点,但我不太确定它如何与最新版本的 networkx 交互(API 发生了一些变化)。如果我有时间,我将尝试启动并运行有效的安装。同时,尝试查看this answer -
prog='dot'很重要,但很可能会让您到达您想去的地方。请注意,除了networkx和matplotlib之外,您还需要安装graphviz 和pygraphviz。
标签: python matplotlib plot graph networkx