可以使用python 3从networkx获取层次图吗?

NickDanger66:

我正在尝试使用networkx.正确显示的所有图表来显示我的类层次结构的树状图,并且显示正常但是作为具有交叉边缘的圆形图,它是一个纯层次结构,看来我应该能够将其显示为树。

我已经在Google上进行了广泛的搜索,提供的每个解决方案都涉及使用pygraphviz...,但PyGraphviz不适用于Python 3(来自pygraphviz站点的文档)

有没有人能够在Python 3中获得树形图显示?

乔尔:

[向下滚动以查看代码产生什么样的输出]

编辑(2019年11月7日),我已经在编写的软件包中添加了一个更完善的版本:https : //epidemicsonnetworks.readthedocs.io/en/latest/_modules/EoN/auxiliary.html#hierarchy_pos此处的代码与此处的版本之间的主要区别在于,此处的代码为给定节点的所有子节点提供相同的水平空间,而该链接之后的代码在确定分配多少空间时还考虑节点具有多少后代。 。

编辑(2019年1月19日),我将代码更新为更加健壮:它现在无需修改即可用于有向图和无向图,不再需要用户指定根,并且在运行之前测试图是否为树(如果没有测试,它将具有无限递归-有关处理非树的方法,请参见user2479115的答案)。

编辑(2018年8月27日)如果您想创建一个节点在根节点周围显示为圆环的图,右下方的代码将显示一个简单的修改即可

编辑(2017年9月17日)我认为现在应该解决OP所带来的pygraphviz问题。因此,pygraphviz可能是我在下面获得的更好的解决方案。


这是定义位置的简单递归程序。递归发生在中_hierarchy_pos,由调用hierarchy_pos的主要作用hierarcy_pos是进行一些测试,以确保图形在进入递归之前是合适的:

import networkx as nx
import random


def hierarchy_pos(G, root=None, width=1., vert_gap = 0.2, vert_loc = 0, xcenter = 0.5):

    '''
    From Joel's answer at https://stackoverflow.com/a/29597209/2966723.  
    Licensed under Creative Commons Attribution-Share Alike 

    If the graph is a tree this will return the positions to plot this in a 
    hierarchical layout.

    G: the graph (must be a tree)

    root: the root node of current branch 
    - if the tree is directed and this is not given, 
      the root will be found and used
    - if the tree is directed and this is given, then 
      the positions will be just for the descendants of this node.
    - if the tree is undirected and not given, 
      then a random choice will be used.

    width: horizontal space allocated for this branch - avoids overlap with other branches

    vert_gap: gap between levels of hierarchy

    vert_loc: vertical location of root

    xcenter: horizontal location of root
    '''
    if not nx.is_tree(G):
        raise TypeError('cannot use hierarchy_pos on a graph that is not a tree')

    if root is None:
        if isinstance(G, nx.DiGraph):
            root = next(iter(nx.topological_sort(G)))  #allows back compatibility with nx version 1.11
        else:
            root = random.choice(list(G.nodes))

    def _hierarchy_pos(G, root, width=1., vert_gap = 0.2, vert_loc = 0, xcenter = 0.5, pos = None, parent = None):
        '''
        see hierarchy_pos docstring for most arguments

        pos: a dict saying where all nodes go if they have been assigned
        parent: parent of this branch. - only affects it if non-directed

        '''

        if pos is None:
            pos = {root:(xcenter,vert_loc)}
        else:
            pos[root] = (xcenter, vert_loc)
        children = list(G.neighbors(root))
        if not isinstance(G, nx.DiGraph) and parent is not None:
            children.remove(parent)  
        if len(children)!=0:
            dx = width/len(children) 
            nextx = xcenter - width/2 - dx/2
            for child in children:
                nextx += dx
                pos = _hierarchy_pos(G,child, width = dx, vert_gap = vert_gap, 
                                    vert_loc = vert_loc-vert_gap, xcenter=nextx,
                                    pos=pos, parent = root)
        return pos


    return _hierarchy_pos(G, root, width, vert_gap, vert_loc, xcenter)

以及示例用法:

import matplotlib.pyplot as plt
import networkx as nx
G=nx.Graph()
G.add_edges_from([(1,2), (1,3), (1,4), (2,5), (2,6), (2,7), (3,8), (3,9), (4,10),
                  (5,11), (5,12), (6,13)])
pos = hierarchy_pos(G,1)    
nx.draw(G, pos=pos, with_labels=True)
plt.savefig('hierarchy.png')

在此处输入图片说明

理想情况下,这应该根据事物下方的宽度重新调整水平间距。我现在没有尝试。

径向膨胀

假设您希望绘图如下所示:

在此处输入图片说明

这是代码:

pos = hierarchy_pos(G, 0, width = 2*math.pi, xcenter=0)
new_pos = {u:(r*math.cos(theta),r*math.sin(theta)) for u, (theta, r) in pos.items()}
nx.draw(G, pos=new_pos, node_size = 50)
nx.draw_networkx_nodes(G, pos=new_pos, nodelist = [0], node_color = 'blue', node_size = 200)

编辑 -感谢Deepak Saini注意到曾经出现在有向图中的错误

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

我可以使用python的SimpleHTTPServer设置标头吗?

我可以使用python的SimpleHTTPServer设置标头吗?

Python中可以使用静态类变量吗?

我可以使用python安装Docker容器吗?

可以使用此Python“静态变量” hack吗?

在Python3中遍历文件的行时可以使用tell()的替代方法吗?

我可以使用IF语句导入模块吗?以后可以在python脚本中导入吗?

我可以使用默认字节不是Unicode的Python 3吗?

我可以使用pip在Python 3中安装Python 2软件包吗?

我可以使用python脚本获取用户登录Maximo时运行的查询吗?

AWS-Lambda可以使用调用C的Python吗?

在Python中,函数中可以使用循环吗?

bigquery python API中的查询可以使用python变量吗?

我可以使用Powershell获取json中属性的层次结构路径吗?

可以使用Highstock制作此股票图吗?

可以使用Python编写Azure函数吗?

我可以使用函数在python中导入模块吗

在Python 2.7中可以使用resume()函数吗?

可以使用morris.js创建SED图吗?

我可以使用python来CSP吗?

可以使用python模拟进行生产吗?

nameko可以使用python3吗?

可以使用 Python 作为数据库语言吗?

Python-我可以使用-date.strptime吗

我可以使用没有括号的python方法吗?

Python3:可以使用命名函数定义进行列表理解吗?

可以使用对象调用python内置函数吗

我可以使用 python VLC 流式传输文件吗?

我可以使用 python 模块的 main 进行测试吗?