我想使用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.
您的两个图表不匹配。不过,我将尝试使用 graphviz 的 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..
输出: