在 Python3 中绘制节点和边的网络
Drawing a network with nodes and edges in Python3
我编写了一个算法来执行 dijkstra 算法。这是我在 A 级课程作业中制作的数学复习游戏。
我有这个数据:
Vertices: {'M', 'Y', 'X', 'C', 'F', 'Q'}
Edges: defaultdict(<class 'list'>, {'X': ['Y'], 'C': ['M'], 'M': ['C', 'F', 'Y'], 'Q': ['F'], 'Y': ['X', 'M'], 'F': ['M', 'Q']})
Weights: {('M', 'C'): 44, ('Q', 'F'): 27, ('Y', 'X'): 42, ('X', 'Y'): 42, ('Y', 'M'): 6, ('M', 'F'): 9, ('M', 'Y'): 6, ('F', 'Q'): 27, ('F', 'M'): 9, ('C', 'M'): 44}
这些值是随机的,每次都不一样。
我可以用什么来可视化网络以使其更清晰,比如节点(顶点)和弧(边)?或者有没有一种方法可以使用像 print("o----o")
.
这样的打印语句来可视化它
您可以创建一个 class Network
来用顶点表示每条边,并创建一个 __repr__
自定义可视化方法:
tree = {'X': ['Y'], 'C': ['M'], 'M': ['C', 'F', 'Y'], 'Q': ['F'], 'Y': ['X', 'M'], 'F': ['M', 'Q']}
weights = {('M', 'C'): 44, ('Q', 'F'): 27, ('Y', 'X'): 42, ('X', 'Y'): 42, ('Y', 'M'): 6, ('M', 'F'): 9, ('M', 'Y'): 6, ('F', 'Q'): 27, ('F', 'M'): 9, ('C', 'M'): 44}
class Vertex:
def __init__(self, vertex, children):
self.vertex = vertex
self.children = children
def __repr__(self):
return ' -- '.join('{} -> {}:{}'.format(self.vertex, i, weights.get((self.vertex, i), weights.get((i, self.vertex), None))) for i in self.children)
class Network:
def __init__(self, tree):
self.__full_tree = [Vertex(*i) for i in tree.items()]
def __repr__(self):
return '\n'.join(repr(i) for i in self.__full_tree)
full_tree = Network(tree)
print(full_tree)
输出:
X -> Y:42
C -> M:44
M -> C:44 -- M -> F:9 -- M -> Y:6
Q -> F:27
Y -> X:42 -- Y -> M:6
F -> M:9 -- F -> Q:27
虽然它远非教科书般的表现,但它确实给出了基本思想。如果您正在寻找更专业的图表,请参阅下面@mattmilten 的回答提供的链接。
看看networkx, plot.ly, or graph-tool。我不能推荐一些基于文本的 ASCII 艺术类可视化。使用精心制作的包可以让您有更多的自由,还可以处理更复杂的数据,其中可视化设置起来并不那么容易。
networkx
包的示例。我们将需要您提供的 Weights
来构建图表。
import matplotlib.pyplot as plt
import networkx as nx
%matplotlib notebook
Weights = {('M', 'C'): 44, ('Q', 'F'): 27, ('Y', 'X'): 42, ('X', 'Y'): 42, ('Y', 'M'): 6, ('M', 'F'): 9, ('M', 'Y'): 6, ('F', 'Q'): 27, ('F', 'M'): 9, ('C', 'M'): 44}
G = nx.Graph()
# each edge is a tuple of the form (node1, node2, {'weight': weight})
edges = [(k[0], k[1], {'weight': v}) for k, v in Weights.items()]
G.add_edges_from(edges)
pos = nx.spring_layout(G) # positions for all nodes
# nodes
nx.draw_networkx_nodes(G,pos,node_size=700)
# labels
nx.draw_networkx_labels(G,pos,font_size=20,font_family='sans-serif')
# edges
nx.draw_networkx_edges(G,pos,edgelist=edges, width=6)
# weights
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
布局
代码修改自此 Tutorial by Aric Hagberg and 。
我编写了一个算法来执行 dijkstra 算法。这是我在 A 级课程作业中制作的数学复习游戏。
我有这个数据:
Vertices: {'M', 'Y', 'X', 'C', 'F', 'Q'}
Edges: defaultdict(<class 'list'>, {'X': ['Y'], 'C': ['M'], 'M': ['C', 'F', 'Y'], 'Q': ['F'], 'Y': ['X', 'M'], 'F': ['M', 'Q']})
Weights: {('M', 'C'): 44, ('Q', 'F'): 27, ('Y', 'X'): 42, ('X', 'Y'): 42, ('Y', 'M'): 6, ('M', 'F'): 9, ('M', 'Y'): 6, ('F', 'Q'): 27, ('F', 'M'): 9, ('C', 'M'): 44}
这些值是随机的,每次都不一样。
我可以用什么来可视化网络以使其更清晰,比如节点(顶点)和弧(边)?或者有没有一种方法可以使用像 print("o----o")
.
您可以创建一个 class Network
来用顶点表示每条边,并创建一个 __repr__
自定义可视化方法:
tree = {'X': ['Y'], 'C': ['M'], 'M': ['C', 'F', 'Y'], 'Q': ['F'], 'Y': ['X', 'M'], 'F': ['M', 'Q']}
weights = {('M', 'C'): 44, ('Q', 'F'): 27, ('Y', 'X'): 42, ('X', 'Y'): 42, ('Y', 'M'): 6, ('M', 'F'): 9, ('M', 'Y'): 6, ('F', 'Q'): 27, ('F', 'M'): 9, ('C', 'M'): 44}
class Vertex:
def __init__(self, vertex, children):
self.vertex = vertex
self.children = children
def __repr__(self):
return ' -- '.join('{} -> {}:{}'.format(self.vertex, i, weights.get((self.vertex, i), weights.get((i, self.vertex), None))) for i in self.children)
class Network:
def __init__(self, tree):
self.__full_tree = [Vertex(*i) for i in tree.items()]
def __repr__(self):
return '\n'.join(repr(i) for i in self.__full_tree)
full_tree = Network(tree)
print(full_tree)
输出:
X -> Y:42
C -> M:44
M -> C:44 -- M -> F:9 -- M -> Y:6
Q -> F:27
Y -> X:42 -- Y -> M:6
F -> M:9 -- F -> Q:27
虽然它远非教科书般的表现,但它确实给出了基本思想。如果您正在寻找更专业的图表,请参阅下面@mattmilten 的回答提供的链接。
看看networkx, plot.ly, or graph-tool。我不能推荐一些基于文本的 ASCII 艺术类可视化。使用精心制作的包可以让您有更多的自由,还可以处理更复杂的数据,其中可视化设置起来并不那么容易。
networkx
包的示例。我们将需要您提供的 Weights
来构建图表。
import matplotlib.pyplot as plt
import networkx as nx
%matplotlib notebook
Weights = {('M', 'C'): 44, ('Q', 'F'): 27, ('Y', 'X'): 42, ('X', 'Y'): 42, ('Y', 'M'): 6, ('M', 'F'): 9, ('M', 'Y'): 6, ('F', 'Q'): 27, ('F', 'M'): 9, ('C', 'M'): 44}
G = nx.Graph()
# each edge is a tuple of the form (node1, node2, {'weight': weight})
edges = [(k[0], k[1], {'weight': v}) for k, v in Weights.items()]
G.add_edges_from(edges)
pos = nx.spring_layout(G) # positions for all nodes
# nodes
nx.draw_networkx_nodes(G,pos,node_size=700)
# labels
nx.draw_networkx_labels(G,pos,font_size=20,font_family='sans-serif')
# edges
nx.draw_networkx_edges(G,pos,edgelist=edges, width=6)
# weights
labels = nx.get_edge_attributes(G,'weight')
nx.draw_networkx_edge_labels(G,pos,edge_labels=labels)
布局
代码修改自此 Tutorial by Aric Hagberg and