首页 > 解决方案 > 从 py2neo 查询获得的 networkx 中带有标签的绘图图

问题描述

我正在使用Jupyter笔记本运行一些数据分析,其中我有一个可变长度匹配的查询,如下所示:

MATCH p=(s:Skill)-[:BROADER*0..3]->(s)
WHERE s.label='py2neo' or s.label='Python'
RETURN p

我想将其结果绘制为图表,使用networkx.

到目前为止,我找到了两个不满意的解决方案。基于此处的笔记本,我可以使用 cypher magic 生成一个图形,其结果可以直接被networkx模块理解。

result = %cypher MATCH p=(s:Skill)-[:BROADER*0..3]->(s) WHERE s.label='py2neo' or s.label='Python' RETURN p

nx.draw(result.get_graph())

但是,我无法找到将标签添加到情节的方法。

该解决方案绕过py2neo. 只要py2neo我不使用可变长度模式,我就可以在图表上放置标签。

例子:

query='''MATCH p=(s1:Skill)-[:BROADER]->(s2)
WHERE s1.label='py2neo' or s1.label='Python'
RETURN s1.label as child, s2.label as parent'''

df = sgraph.data(query)

然后,从 Stackoverflow 中的响应复制(稍后我将链接)我可以手动构建图表

G=nx.DiGraph()   
G.add_nodes_from(list(set(list(df.iloc[:,0]) + list(df.iloc[:,1]))))

#Add edges

tuples = [tuple(x) for x in df.values] 
G.add_edges_from(tuples)
G.number_of_edges()

#Perform Graph Drawing
#A star network  (sort of)
nx.draw_networkx(G)
plt.show()

有了这个,我得到了一个带有标签的图表,但是为了得到可变长度匹配之类的东西,我应该使用多个查询。

但我怎样才能两全其美?我更喜欢一个py2neo解决方案。改写:我怎样才能py2neo返回一个图表(不是表格),然后能够将这些信息传递给networkx,能够从多个可能的标签中确定哪些是要显示在图表中的标签?

标签: pythonneo4jpy2neo

解决方案


最后的问题是如何从与某个查询匹配的子图中获取包含所有边的表。

Cypher诀窍是:

MATCH (source:Skill)-[:BROADER*0..7]->(dest:Skill)
WHERE source.label_en in ['skill1','skill2'] 
WITH COLLECT(DISTINCT source)+COLLECT(dest) AS myNodes
UNWIND myNodes as myNode
MATCH p=(myNode)-[:BROADER]->(neighbor)
WHERE neighbor in myNodes
RETURN myNode.label_en as child ,neighbor.label_en as parent

前两行获取属于所述子图的节点。最后五个将其展开为由有向边连接的节点对。第二0MATCH允许收集属于原始列表的孤立节点。


与 2019 年一样,使用当前py2neo的软件包,这件事的一种工作方式是

query = '''
MATCH (source:Skill)-[:BROADER*0..7]->(dest:Skill)
WHERE source.label_en in ['skill1','skill2'] 
WITH COLLECT(DISTINCT source)+COLLECT(dest) AS myNodes
UNWIND myNodes as myNode
MATCH p=(myNode)-[:BROADER]->(neighbor)
WHERE neighbor in myNodes
RETURN myNode.label_en as child ,neighbor.label_en as parent
'''

df = pd.DataFrame(graph.run(query).data())

G=nx.DiGraph()   
G.add_nodes_from(list(set(list(df['child']) + list(df.loc['parent']))))

#Add edges

tuples = [tuple(x) for x in df.values] 
G.add_edges_from(tuples)
G.number_of_edges()

#Perform Graph Drawing
#A star network  (sort of)
nx.draw_networkx(G)
plt.show()

推荐阅读