【问题标题】:Tree plotting in PythonPython中的树形图
【发布时间】:2011-12-01 23:40:36
【问题描述】:

我想使用 Python 绘制树。决策树、组织结构图等。任何可以帮助我的库?

【问题讨论】:

    标签: python plot tree data-visualization visualization


    【解决方案1】:

    我开发了ETE,这是一个 python 包,用于编程树渲染和可视化等。您可以创建自己的layout functions 并生成自定义tree images

    它专注于系统发育,但它实际上可以处理任何类型的层次树(聚类、决策树等)

    【讨论】:

    • @Fxs7576 有一个工作分支将很快合并,添加 Qt5 支持。 github.com/etetoolkit/ete/pull/284
    • 它不适用于 Windows 吗?您的安装指南没有 windows 部分,如果我运行 conda install 行,它找不到包。
    • 对于windows,看起来你可以使用pip install ete3安装。
    • 从字面上看,我发现的唯一一个可能是 pip installed 的包,它会开箱即用。
    • 看起来很有希望
    【解决方案2】:

    有graphviz - http://www.graphviz.org/。它使用“DOT”语言来绘制图形。您可以自己生成 DOT 代码,也可以使用 pydot - https://github.com/pydot/pydot。您还可以使用 networkx - http://networkx.lanl.gov/tutorial/tutorial.html#drawing-graphs,它可以轻松绘制到 graphviz 或 matplotlib。

    networkx + matplotlib + graphviz 为您提供了最大的灵活性和功能,但您需要安装很多。

    如果您想要快速解决方案,请尝试:

    安装 Graphviz。

    open('hello.dot','w').write("digraph G {Hello->World}")
    import subprocess
    subprocess.call(["path/to/dot.exe","-Tpng","hello.dot","-o","graph1.png"]) 
    # I think this is right - try it form the command line to debug
    

    然后你安装 pydot,因为 pydot 已经为你做了这个。然后你可以使用networkx来“驱动”pydot。

    【讨论】:

    • NetworX 看起来不错。唯一的事情是我需要一个外部库来生成图像文件。我可以在节点之间生成弧吗?
    • 哪个库? NetworkX 可以处理几个不同的。他们似乎喜欢 Matplotlib,这里有安装指南:matplotlib.sourceforge.net/users/installing.html
    • Matplotlib 不支持图表,至少是独立的。
    • NetworkX。 Graphviz 历史上以读取“DOT”文件而闻名,但 IMO 的 NetworkXEteiGraph 产生的效果远按照现代标准获得更好的结果,并且不需要将另一种语言与 Python 混合使用。
    【解决方案3】:

    对于基本的可视化,我会考虑使用treelib

    它非常简单易用

     from treelib import Node, Tree
    
     tree = Tree()
    
     tree.create_node("Harry", "harry")  # No parent means its the root node
     tree.create_node("Jane",  "jane"   , parent="harry")
     tree.create_node("Bill",  "bill"   , parent="harry")
     tree.create_node("Diane", "diane"  , parent="jane")
     tree.create_node("Mary",  "mary"   , parent="diane")
     tree.create_node("Mark",  "mark"   , parent="jane")
    
     tree.show()
    

    输出:

    Harry
    ├── Bill
    └── Jane
        ├── Diane
        │   └── Mary
        └── Mark 
    

    【讨论】:

    • 非常感谢您的意见,确实易于使用。此外,一旦你构建了一个树来生成树的 graphviz 格式,还有一个很好的方法:tree.to_graphviz()。因此,您可以在任何在线或离线工具中使用它。
    【解决方案4】:

    Plotly 可以使用 igraph 绘制树形图。这些天你也可以离线使用它。下面的示例旨在在 Jupyter 笔记本中运行

    import plotly.plotly as py
    import plotly.graph_objs as go
    
    import igraph
    from igraph import *
    # I do not endorse importing * like this
    
    #Set Up Tree with igraph
    
    nr_vertices = 25
    v_label = map(str, range(nr_vertices))
    G = Graph.Tree(nr_vertices, 2) # 2 stands for children number
    lay = G.layout('rt')
    
    position = {k: lay[k] for k in range(nr_vertices)}
    Y = [lay[k][1] for k in range(nr_vertices)]
    M = max(Y)
    
    es = EdgeSeq(G) # sequence of edges
    E = [e.tuple for e in G.es] # list of edges
    
    L = len(position)
    Xn = [position[k][0] for k in range(L)]
    Yn = [2*M-position[k][1] for k in range(L)]
    Xe = []
    Ye = []
    for edge in E:
        Xe+=[position[edge[0]][0],position[edge[1]][0], None]
        Ye+=[2*M-position[edge[0]][1],2*M-position[edge[1]][1], None] 
    
    labels = v_label
    
    #Create Plotly Traces
    
    lines = go.Scatter(x=Xe,
                       y=Ye,
                       mode='lines',
                       line=dict(color='rgb(210,210,210)', width=1),
                       hoverinfo='none'
                       )
    dots = go.Scatter(x=Xn,
                      y=Yn,
                      mode='markers',
                      name='',
                      marker=dict(symbol='dot',
                                    size=18, 
                                    color='#6175c1',    #'#DB4551', 
                                    line=dict(color='rgb(50,50,50)', width=1)
                                    ),
                      text=labels,
                      hoverinfo='text',
                      opacity=0.8
                      )
    
    # Create Text Inside the Circle via Annotations
    
    def make_annotations(pos, text, font_size=10, 
                         font_color='rgb(250,250,250)'):
        L=len(pos)
        if len(text)!=L:
            raise ValueError('The lists pos and text must have the same len')
        annotations = go.Annotations()
        for k in range(L):
            annotations.append(
                go.Annotation(
                    text=labels[k], # or replace labels with a different list 
                                    # for the text within the circle  
                    x=pos[k][0], y=2*M-position[k][1],
                    xref='x1', yref='y1',
                    font=dict(color=font_color, size=font_size),
                    showarrow=False)
            )
        return annotations  
    
    # Add Axis Specifications and Create the Layout
    
    axis = dict(showline=False, # hide axis line, grid, ticklabels and  title
                zeroline=False,
                showgrid=False,
                showticklabels=False,
                )
    
    layout = dict(title= 'Tree with Reingold-Tilford Layout',  
                  annotations=make_annotations(position, v_label),
                  font=dict(size=12),
                  showlegend=False,
                  xaxis=go.XAxis(axis),
                  yaxis=go.YAxis(axis),          
                  margin=dict(l=40, r=40, b=85, t=100),
                  hovermode='closest',
                  plot_bgcolor='rgb(248,248,248)'          
                  )
    
    # Plot
    
    data=go.Data([lines, dots])
    fig=dict(data=data, layout=layout)
    fig['layout'].update(annotations=make_annotations(position, v_label))
    py.iplot(fig, filename='Tree-Reingold-Tilf')
    # use py.plot instead of py.iplot if you're not using a Jupyter notebook
    

    Output

    【讨论】:

    • 我从这里收到一条难以理解的错误消息:DeprecationWarning Traceback (most recent call last) <ipython-input-44-cfbb1d309447> in <module>() ----> 4 import igraph DeprecationWarning: To avoid name collision with the igraph project, this visualization library has been renamed to 'jgraph'. Please upgrade when convenient. 我不知道要升级什么:igraphjgraph 或其他内容。我有所有东西的最新版本。重写代码以引用 jgraph 不起作用。 pip install jgraph 无效:jgraph 没有 Graph 成员。等等:(
    • 找到了可能的答案:stackoverflow.com/questions/36200707/…
    • 我得到了这个工作,但它需要用 plotly 设置一个帐户,所以我寻找免费的替代品。 python-igraph(与 igraph 不同)有一些绘图功能igraph.org/python/doc/tutorial/tutorial.html。很难安装;在 Mac OS X 上,经过痛苦的兔子洞之旅后,“brew install cairo”被证明是必要且足够的。
    • 为什么会出现 TypeError:'map' 类型的对象没有 len()
    【解决方案5】:

    对于 2021 年的解决方案,我编写了 TreantJS 库的 Python 包装器。该包创建一个带有树形可视化的 HTML 文件。用户可以选择调用 R 的 webshot 库来渲染树的高分辨率屏幕截图。该软件包是相当新的,因此任何 PR、错误报告或问题中的功能请求将不胜感激!请参阅:https://github.com/Luke-Poeppel/treeplotter

    该软件包有一些烦人的安装要求(请参阅Installation.md),因此我编写了一个 MacOS 安装助手(在 Catalina 和 Big Sur 上测试过)。任何减少这些限制的提示也将受到欢迎。

    【讨论】:

      【解决方案6】:

      这是试用版,但 Google 有一个 GraphViz api。如果您只想快速可视化图表,但不想安装任何软件,这很方便。

      【讨论】:

      • 此 API 已弃用并关闭
      猜你喜欢
      • 2018-11-21
      • 1970-01-01
      • 1970-01-01
      • 2021-02-09
      • 1970-01-01
      • 2011-07-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多