问题描述
我正在做一个程序,我正在从现有的 python 存储库构建图形。 我正在使用 networkx 在所有依赖项上绘制图形,并将每个节点/文件的大小设置为相应文件的复杂度。
代码目前看起来像这样,但它确实是与此问题相关的最底层:
import ast
from radon.visitors import ComplexityVisitor
import re
import os
import networkx as nx
import matplotlib.pyplot as plt
class Vert:
def __init__(self,name,size,path,edges):
self.name = name
self.size = size
self.path = path
self.edges = edges
rootDir = "/home/ask/Git/Zeeguu-API/"
from pathlib import Path
def extract_importandClass_from_line(unline):
x = re.search("^import (\S+)",unline)
x = re.search("^from (\S+)",unline)
return x.group(1)#,c.group(1).split('(')[0]
def extractClass(inline):
c = re.search("^class (\S+)",inline)
return c.group(1).split('(')[0]
def importsAndClass(file):
lines = [line for line in open(file)]
classes = []
all_imports = []
for line in lines:
try:
imports = extract_importandClass_from_line(line)
all_imports.append(imports.rsplit('.',1)[-1])
except:
try:
class1 = extractClass(line)
classes.append(class1)
except:
continue
return all_imports,classes
G = nx.DiGraph()
nodes = set()
nodeNames = set()
for file in Path(rootDir).rglob("*.py"):
# opening file,and looking at contents
f = open(file,"r")
s = f.read()
# analyzing complexity
analyzer = ComplexityVisitor.from_code(s)
# getting the file name
splitFile = os.path.splitext(file.name)
#getting imports
imports,classes = importsAndClass(file)
#creating vertex
v = Vert(splitFile[0],analyzer.total_complexity,file,imports)
nodes.add(v)
nodeNames.add(splitFile[0])
for vert in nodes:
G.add_node(vert.name)
for i in vert.edges:
if i in nodeNames:
G.add_edge(vert.name,i)
node_sizes = [V.size * 100 for V in nodes]
plt.figure(figsize=(100,100))
nx.draw(G,font_weight='bold',with_labels = True,node_size=node_sizes)
plt.show()
所以,最后发生的事情是我有一个 Vert 对象列表,所有这些对象都有一个与它们相关的大小字段。
然后我通过遍历所有这些大小并将它们乘以 100 来创建 node_sizes
列表。
当我运行它时,它在调用 nx.draw()
时失败并出现以下错误。
ValueError: s must be a scalar,or float array-like with the same size as x and y
如果我从 node_size
中删除 nx.draw()
参数,那么它运行良好,并显示我的图像。
这我真的不明白。什么是 s、x 和 y?
然后我做了一个玩具示例,看看它是否可以在较小的环境中工作: 类垂直:
# default constructor
def __init__(self,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)
for e in v.edges:
G.add_edge(v.name,e)
node_sizes = [V.size * 100 for V in nodes]
nx.draw(G,node_size=node_sizes)
plt.show()
在这里,我或多或少做了同样的事情,但这次它起作用了,而且我的图形以正确的尺寸绘制。在这两个示例中,node_sizes
列表是一个整数列表。
在触发此问题的第一个示例中,我做错了什么?
编辑:
我现在做了一些调试,发现G中的节点数:
G.number_of_nodes()
是 229,而我用来构建图形的节点集中的元素数量是 272。 我想这可能是问题所在。 但这怎么可能?我像这样构建图表:
for vert in nodes:
G.add_node(vert.name)
for i in vert.edges:
if i in nodeNames:
G.add_edge(vert.name,i)
我在哪里迭代节点中的每个项目(这是一个集合,因此没有重复项)那么怎么可能不是节点的每个元素都被添加到图中?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)