如何在Python中绘制带有节点标签的树?

问题描述 投票:0回答:1

我想使用Python中的任何工具重现下图:

(这是我使用 Inkscape 创建的 [^Furnival1974] 中第 75 页图 5 的一部分)。

我不仅想重现这棵树,还想使用 Python 编程重现其他树。 使用ETE,我写了这个:

from ete3 import Tree

t = Tree("(12345, (1234, (1235, (123)), (1245, (124, 125, (12))), (1345, (134, (135, (13))), 145), 2345));")
t.show()

产生:

树是水平的这一事实不是问题。对我来说主要问题是节点没有标签。该工具似乎只知道叶子,而我的需要是在节点上有标签。为什么我可以使用Python创建所需的树?

[^Furnival1974]:Furnival, G. M. 和 Wilson, R. W. (1974)。突飞猛进的回归。技术计量学。 16:499-511.

python plot tree
1个回答
0
投票

您的两个图表不匹配。不过,我将尝试使用 的 Python 接口来重现第一个。因此,假设您有一个字符串作为输入:

s = """(
    12345,
        (1234, 1235, (123,),
        1245, (124, 125, (12,)),
        1345, (134, 135, (13,), 145),
        2345
        )
    )"""

您可以尝试如下所示:

#pip install graphviz
from graphviz import Digraph
from ast import literal_eval
from itertools import chain, product

nodes = {"12345": "588", "1234": "592", "1235": "596", "1245": "596", "1345": "605",
         "2345": "660", "123": "597", "124": "615", "125": "597", "134": "612",
         "135": "618", "145": "618", "12": "615", "13": "641"} # nodes/labels

def edgewise(obj):
    for p,t in zip(obj, obj[1:]):
        if not isinstance(p, tuple) and isinstance(t, tuple):
            yield product([str(p)], (str(i) for i in t if not isinstance(i, tuple)))
        if isinstance(t, tuple):
            yield from edgewise(t)

edges = list(chain.from_iterable(edgewise(literal_eval(s))))

config = {
    "graph_attr": {"size": "5!"},
    "node_attr": {"shape": "plain", "fontsize": "18", "fontname": "Times-Roman"},
    "edge_attr": {"dir": "none", "penwidth": "2"}
}

dot = graphviz.Digraph(**config)

for n, l in nodes.items():
    dot.node(name=n, label=rf"{n}\n({l})")

for e in edges:
    dot.edge(*e)

# dot.render(filename="output", format="pdf", view=True) # uncomment to save a file/image..

输出:

© www.soinside.com 2019 - 2024. All rights reserved.