绘制嵌套的 networkx 图
Drawing nested networkx graphs
我想知道是否有办法在 python 中绘制嵌套的 networkx 图。
我可以使用 nx.draw_(...) 方法调用成功绘制这些图形,如 networkx 文档中所述,但我正在使用它for 要求其中一个节点本身是一个图(想象一个房间网络,在顶层,在下一层的房间内有一个 areas/zones 网络)。我想用 matplotlib 或类似的东西来展示这个。
如有任何想法,我们将不胜感激。
编辑
通过定义递归函数,您可能比我原来的答案做得更好。这是该递归函数的外观的粗略概述。我在下面的回答给出了一种不太优雅的方法,可以针对特定情况轻松调整,但如果你经常这样做,你可能需要这个递归版本。
def recursive_draw(G,currentscalefactor=0.1,center_loc=(0,0),nodesize=300, shrink=0.1):
pos = nx.spring_layout(G)
scale(pos,currentscalefactor) #rescale distances to be smaller
shift(pos,center_loc) #you'll have to write your own code to shift all positions to be centered at center_loc
nx.draw(G,pos=pos, nodesize=nodesize)
for node in G.nodes_iter():
if type(node)==Graph: # or diGraph etc...
recursive_draw(node,currentscalefactor=shrink*currentscalefactor,center_loc=pos[node], nodesize = nodesize*shrink, shrink=shrink)
如果有人创建递归函数,请将其添加为单独的答案,并给我评论。我将从这个答案中指出它。
原回答
这是第一遍(我希望在一天结束前编辑成完整的答案,但我认为这将帮助您完成大部分工作):
import networkx as nx
import pylab as py
G = nx.Graph()
H = nx.Graph()
H.add_edges_from([(1,2), (2,3), (1,3)])
I = nx.Graph()
I.add_edges_from([(1,3), (3,2)])
G.add_edge(H,I)
Gpos = nx.spring_layout(G)
Hpos = nx.spring_layout(H)
Ipos = nx.spring_layout(I)
scalefactor = 0.1
for node in H.nodes():
Hpos[node] = Hpos[node]*scalefactor + Gpos[H]
for node in I.nodes():
Ipos[node] = Ipos[node]*scalefactor + Gpos[I]
nx.draw_networkx_edges(G, pos = Gpos)
nx.draw_networkx_nodes(G, pos = Gpos, node_color = 'b', node_size = 15000, alpha = 0.5)
nx.draw(H, pos = Hpos, with_labels = True)
nx.draw(I, pos = Ipos, with_labels = True)
py.savefig('tmp.png')
我认为你应该做的主要的额外事情是使每个子节点居中。这将需要为每个子图识别 xmin、xmax、ymin 和 ymax 并进行调整。您可能还想玩一下比例因子。
我想知道是否有办法在 python 中绘制嵌套的 networkx 图。
我可以使用 nx.draw_(...) 方法调用成功绘制这些图形,如 networkx 文档中所述,但我正在使用它for 要求其中一个节点本身是一个图(想象一个房间网络,在顶层,在下一层的房间内有一个 areas/zones 网络)。我想用 matplotlib 或类似的东西来展示这个。
如有任何想法,我们将不胜感激。
编辑 通过定义递归函数,您可能比我原来的答案做得更好。这是该递归函数的外观的粗略概述。我在下面的回答给出了一种不太优雅的方法,可以针对特定情况轻松调整,但如果你经常这样做,你可能需要这个递归版本。
def recursive_draw(G,currentscalefactor=0.1,center_loc=(0,0),nodesize=300, shrink=0.1):
pos = nx.spring_layout(G)
scale(pos,currentscalefactor) #rescale distances to be smaller
shift(pos,center_loc) #you'll have to write your own code to shift all positions to be centered at center_loc
nx.draw(G,pos=pos, nodesize=nodesize)
for node in G.nodes_iter():
if type(node)==Graph: # or diGraph etc...
recursive_draw(node,currentscalefactor=shrink*currentscalefactor,center_loc=pos[node], nodesize = nodesize*shrink, shrink=shrink)
如果有人创建递归函数,请将其添加为单独的答案,并给我评论。我将从这个答案中指出它。
原回答 这是第一遍(我希望在一天结束前编辑成完整的答案,但我认为这将帮助您完成大部分工作):
import networkx as nx
import pylab as py
G = nx.Graph()
H = nx.Graph()
H.add_edges_from([(1,2), (2,3), (1,3)])
I = nx.Graph()
I.add_edges_from([(1,3), (3,2)])
G.add_edge(H,I)
Gpos = nx.spring_layout(G)
Hpos = nx.spring_layout(H)
Ipos = nx.spring_layout(I)
scalefactor = 0.1
for node in H.nodes():
Hpos[node] = Hpos[node]*scalefactor + Gpos[H]
for node in I.nodes():
Ipos[node] = Ipos[node]*scalefactor + Gpos[I]
nx.draw_networkx_edges(G, pos = Gpos)
nx.draw_networkx_nodes(G, pos = Gpos, node_color = 'b', node_size = 15000, alpha = 0.5)
nx.draw(H, pos = Hpos, with_labels = True)
nx.draw(I, pos = Ipos, with_labels = True)
py.savefig('tmp.png')
我认为你应该做的主要的额外事情是使每个子节点居中。这将需要为每个子图识别 xmin、xmax、ymin 和 ymax 并进行调整。您可能还想玩一下比例因子。