【问题标题】:squared nodes in networkx with matplotlib使用matplotlib在networkx中平方节点
【发布时间】:2021-07-25 23:29:18
【问题描述】:

在开始之前,我要指出,这个问题似乎与this one 重复,但这里的解决方案根本无法在python3 中使用当前版本的networkx 编译。该集合不会自行构建等。

所以我有一个 networkx 图表,我使用 matplotlib 绘制。这是它的代码:

class Vert:
  
    # default constructor
    def __init__(self, name, size, edges):
        self.name = name
        self.size = size
        self.edges = edges


import networkx as nx
import matplotlib.pyplot as plt

nodes = []
nodes.append(Vert('A', 1, ['B', 'C']))
nodes.append(Vert('B', 3, ['D']))
nodes.append(Vert('C', 4, ['D']))
nodes.append(Vert('D', 7, []))
nodes.append(Vert('Y', 64, []))

G = nx.DiGraph()
for v  in nodes:
    G.add_node(v.name, s='v')
    for e in v.edges:
        G.add_edge(v.name, e)

node_sizes = [V.size * 100 for V in nodes]
shapes = set((aShape[1]["s"] for aShape in G.nodes(data = True)))

nx.draw(G, font_weight='bold', with_labels = True, node_size=node_sizes, node_shape= shapes)

#plt.savefig('plot.png', bbox_inches='tight')
plt.show()

我需要一些节点具有正方形或三角形,我该怎么做?

【问题讨论】:

标签: python python-3.x matplotlib networkx


【解决方案1】:

旧答案中的代码无法运行,因为add_path() 的语法在写这篇文章后发生了变化。我编辑了旧问题中的答案,但由于我还没有编辑批准权限,因此不会立即显示。

如果你替换

G.add_path([0,2,5])
G.add_path([1,4,3,0])
G.add_path([2,4,0,5])

nx.add_path(G, [0,2,5])
nx.add_path(G, [1,4,3,0])
nx.add_path(G, [2,4,0,5])

那么我相信它应该会成功运行。


编辑:针对下面的评论,这里是一个考虑到形状和大小的工作代码示例。它的风格不是特别干净或一致,但它结合了previous SO question 中的方法和提问者的数据生成方案。

关键部分是从使用nx.draw() 更改为使用nx.draw_networkx_nodes()nx.draw_networkx_edges()nx.draw_networkx_labels() 分别绘制图形的所有部分。有关详细信息,请参阅networkx drawing docs。此更改允许使用 nx.draw_networkx_nodes() 的不同调用来绘制具有不同形状的每组节点。

我做了一些相当不雅的事情来调整情节,包括调整plt.xlimplt.ylimnx.layout.spring_layout()的间距参数(k)。

下面的代码给出了如下图:

class Vert:
  
    # default constructor
    def __init__(self, name, size, edges):
        self.name = name
        self.size = size
        self.edges = edges


import networkx as nx
import matplotlib.pyplot as plt

nodes = []
nodes.append(Vert('A', 1, ['B', 'C']))
nodes.append(Vert('B', 3, ['D']))
nodes.append(Vert('C', 4, ['D']))
nodes.append(Vert('D', 7, []))
nodes.append(Vert('Y', 64, []))

G = nx.DiGraph()

for v  in nodes:
    # Assign 'v' shape to even nodes and square shape to odd nodes.
    if ord(v.name) % 2 == 0:
        G.add_node(v.name, size=v.size, shape='v')
    else:
        G.add_node(v.name, size=v.size, shape='s')
    for e in v.edges:
        G.add_edge(v.name, e)

shapes = set((aShape[1]['shape'] for aShape in G.nodes(data = True)))
pos = nx.layout.spring_layout(G, k=2) #Make k larger to space out nodes more.

for shape in shapes:
    nodelist=[node[0] for node in filter(lambda x: x[1]['shape']==shape,G.nodes(data = True))]
    sizes = [100 * node[1]['size'] for node in filter(lambda x: x[1]['shape']==shape,G.nodes(data = True))]
    #...filter and draw the subset of nodes with the same symbol in the positions that are now known through the use of the layout.
    nx.draw_networkx_nodes(G,
                           pos,
                           node_shape=shape,
                           nodelist=nodelist,
                           node_size=sizes)

# Draw the edges between the nodes and label them
nx.draw_networkx_edges(G,pos)
nx.draw_networkx_labels(G, pos)

plt.xlim(-2, 2) # Expand limits if large nodes spill over plot.
plt.ylim(-2, 2) # Expand limits if large nodes spill over plot.

plt.show()

【讨论】:

  • 我没有在自己的代码中调用“add_path”,而且我真的不知道它的用途。有什么办法可以在我的代码中引入正方形?
  • @Garsty100 -- 我添加了一个基于您的 cmets 的完整解决方案,包括根据形状和大小绘制节点。请注意,我将 size 属性直接添加到图中的每个节点。
猜你喜欢
  • 2018-08-26
  • 1970-01-01
  • 2015-12-05
  • 2019-08-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-07-30
相关资源
最近更新 更多