[英]Networkx in Python - draw node attributes as labels outside the node
我有一个具有特定属性的节点图,我想在 Python 中通过 networkx 绘制该图,其中有几个属性作为节点外节点的标签。
有人可以帮助我如何编写代码来实现这一目标吗?
我的代码中有一个循环生成“interface_?” 防火墙列表(fwList)中每个输入的属性
for y in fwList:
g.add_node(n, type='Firewall')
print 'Firewall ' + str(n) + ' :'
for x in fwList[n]:
g.node[n]['interface_'+str(i)] = x
print 'Interface '+str(i)+' = '+g.node[n]['interface_'+str(i)]
i+=1
i=1
n+=1
然后,稍后我绘制节点和边,如:
pos=nx.spring_layout(g)
nx.draw_networkx_edges(g, pos)
nx.draw_networkx_nodes(g,pos,nodelist=[1,2,3],node_shape='d',node_color='red')
并将其扩展到一些具有其他形状和颜色的新节点。
为了标记单个属性,我在下面的代码中尝试过,但没有用
labels=dict((n,d['interface_1']) for n,d in g.nodes(data=True))
为了将文本从节点中取出,我不知道......
您可以访问“pos”字典中的节点位置。 所以你可以使用 matplotlib 把文本放在任何你喜欢的地方。 例如
In [1]: import networkx as nx
In [2]: G=nx.path_graph(3)
In [3]: pos=nx.spring_layout(G)
In [4]: nx.draw(G,pos)
In [5]: x,y=pos[1]
In [6]: import matplotlib.pyplot as plt
In [7]: plt.text(x,y+0.1,s='some text', bbox=dict(facecolor='red', alpha=0.5),horizontalalignment='center')
Out[7]: <matplotlib.text.Text at 0x4f1e490>
除了 Aric 的答案之外, pos
字典还包含值中的x, y
坐标。 所以你可以操纵它,一个例子可能是:
pos_higher = {}
y_off = 1 # offset on the y axis
for k, v in pos.items():
pos_higher[k] = (v[0], v[1]+y_off)
然后用新位置绘制标签:
nx.draw_networkx_labels(G, pos_higher, labels)
其中G
是您的图形对象并labels
字符串列表。
我喜欢创建一个通过偏移量移动布局的nudge
功能。
import networkx as nx
import matplotlib.pyplot as plt
def nudge(pos, x_shift, y_shift):
return {n:(x + x_shift, y + y_shift) for n,(x,y) in pos.items()}
G = nx.Graph()
G.add_edge('a','b')
G.add_edge('b','c')
G.add_edge('a','c')
pos = nx.spring_layout(G)
pos_nodes = nudge(pos, 0, 0.1) # shift the layout
fig, ax = plt.subplots(1,2,figsize=(12,6))
nx.draw_networkx(G, pos=pos, ax=ax[0]) # default labeling
nx.draw_networkx(G, pos=pos, with_labels=False, ax=ax[1]) # default nodes and edges
nx.draw_networkx_labels(G, pos=pos_nodes, ax=ax[1]) # nudged labels
ax[1].set_ylim(tuple(i*1.1 for i in ax[1].get_ylim())) # expand plot to fit labels
plt.show()
NetworkX 关于draw_networkx_labels
的文档还表明,您可以使用horizontalalignment
draw_networkx_labels
和verticalalignment
draw_networkx_labels
参数来获得简单、开箱即用的解决方案,而无需手动轻推标签。
从文档:
水平对齐 ({'center', 'right', 'left'}) – 水平对齐(默认 ='center')
垂直对齐 ({'center', 'top', 'bottom', 'baseline', 'center_baseline'}) – 垂直对齐 (default='center')
更方便的是,您可以将其与更高级别的 NetworkX 函数一起使用,例如nx.draw()
或nx.draw_spectral
(或其变体),因为这些更高级别的函数参数接受关键字参数,这些关键字参数依次传递到其较低级别的参数中。级功能。
所以下面的代码是一个最低限度可行的代码,它可以满足您的要求,即推动/微移节点外的标签:
G = nx.DiGraph(name='Email Social Network')
nx.draw(G, arrowsize=3, verticalalignment='bottom')
# or:
nx.draw(G, arrowsize=3, verticalalignment='top')
plt.show()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.