networkx 中的平方节点与 matplotlib
squared nodes in networkx with matplotlib
在开始之前,我要指出这个问题似乎与 重复,但这里的解决方案根本无法在 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()
我需要一些节点具有正方形或三角形的形状,我该怎么做?
旧答案中的代码无法 运行,因为自 post 编写以来 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])
那么我相信它应该运行成功。
编辑:为了回应下面的评论,这里是一个考虑了形状和大小的工作代码示例。它不是特别干净或风格一致,但它结合了 中的方法和提问者的数据生成方案。
关键部分是从使用 nx.draw()
更改为使用 nx.draw_networkx_nodes()
、nx.draw_networkx_edges()
和 nx.draw_networkx_labels()
单独绘制图形的所有部分。有关详细信息,请参阅 networkx drawing docs。此更改允许使用不同的 nx.draw_networkx_nodes()
.
调用绘制具有不同形状的每组节点
我做了一些相当不雅的事情来调整情节,包括调整plt.xlim
、plt.ylim
和nx.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()
在开始之前,我要指出这个问题似乎与
所以我有一个 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()
我需要一些节点具有正方形或三角形的形状,我该怎么做?
旧答案中的代码无法 运行,因为自 post 编写以来 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])
那么我相信它应该运行成功。
编辑:为了回应下面的评论,这里是一个考虑了形状和大小的工作代码示例。它不是特别干净或风格一致,但它结合了
关键部分是从使用 nx.draw()
更改为使用 nx.draw_networkx_nodes()
、nx.draw_networkx_edges()
和 nx.draw_networkx_labels()
单独绘制图形的所有部分。有关详细信息,请参阅 networkx drawing docs。此更改允许使用不同的 nx.draw_networkx_nodes()
.
我做了一些相当不雅的事情来调整情节,包括调整plt.xlim
、plt.ylim
和nx.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()