mcpField
E
etetoolkit

etetoolkit

github.com/jaechang-hitsデータ・データベース38469 回インストール1 週間前に更新
リポジトリ

etetoolkit について

ETE Toolkit(ETE3)は、系統樹の探索、編集、可視化を行う Python フレームワークです。進化生物学や比較ゲノム学のワークフロー向けに、複数の形式、NCBI 分類情報、柔軟な描画機能を備えています。

主な機能

  1. 01複数の系統樹形式の読み書き
  2. 02ノードの走査、検索、編集
  3. 03ノードへのメタデータ付与
  4. 04系統樹距離と進化統計の計算
  5. 05NCBI 分類情報の検索と樹の構築
  6. 06スタイルを調整した系統樹描画

活用シーン

  1. 01後続解析に向けた系統樹の整理と剪定
  2. 02メタデータ付き系統樹図の作成
  3. 03樹形比較や最終共通祖先の検索
  4. 04遺伝子系統樹でのオーソログ推定

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/jaechang-hits/sciagent-skills --skill etetoolkit

インストール後、Claude Code で/etetoolkitを入力して読み込まれたか確認します。

詳細

ETE Toolkit:系統樹の解析と可視化

概要

ETE Toolkit(ETE3)は、系統樹の探索、操作、および出版品質の可視化を行うための Python フレームワークです。Newick、NHX、PhyloXML、NeXML 形式の読み書き、ノードへの詳細な注釈付け、プログラムによるツリーの走査、NCBI taxonomy との連携、カスタマイズ可能なツリー図を作成するための柔軟な描画エンジンをサポートしています。ETE3 は、比較ゲノミクス、系統ゲノミクス、進化生物学のワークフローで広く使用されています。

使用する場面

  • Newick、NHX、PhyloXML、NeXML ファイルから系統樹を解析し、プログラムでトポロジーを走査または変更する
  • 可視化や下流解析のために、メタデータ(ブートストラップ値、遺伝子名、分類階級、発現データ)でツリーのノードに注釈を付ける
  • TreeStyle と NodeStyle を使用し、カスタムのノード形状、色、枝の幅、装飾を指定して出版品質のツリー図を描画する
  • NCBI taxonomy ID を系統情報に対応付け、種名を検証する、または分類情報を考慮したツリーを構築する
  • 進化統計量を計算する:枝長、ツリー間距離(Robinson-Foulds)、LCA クエリ、単系統性の検定
  • 比較ゲノミクス用の PhyloTree オブジェクトを構築する — 遺伝子重複/種分化イベントの注釈付け、オーソログ/パラログの推定
  • 下流ツール(BEAST、IQ-TREE など)に渡す前に、プログラムでツリーを刈り込み、再ルート化、またはウルトラメトリック化する
  • ツリー構築前の配列アラインメントには、代わりに biopython-molecular-biology を使用してください

前提条件

  • Python パッケージ:ete3、numpy、PyQt5(インタラクティブな描画用)、lxml(PhyloXML 用)
  • データ要件:Newick 文字列またはツリーファイル。NCBI taxonomy データベース(NCBI モジュールで初回使用時にダウンロードされます)
  • 環境:Python 3.6 以降。TreeStyle による描画とインタラクティブ GUI には PyQt5 が必要です。ヘッドレス描画には xvfb が必要です

インストール前に確認してください:ツールが現在の環境(たとえば pixi/conda 環境内)で既に利用可能な場合があります。まず command -v python を実行し、パスが返された場合は、以下のインストールコマンドを省略してください。pixi プロジェクト内で実行する場合は、python を直接実行するのではなく、pixi run python を使用してください。

pip install ete3 numpy lxml PyQt5
# For headless rendering on Linux servers:
# apt-get install xvfb python3-pyqt5

クイックスタート

from ete3 import Tree

# Load a Newick tree and inspect basic properties
t = Tree("((A:0.1,B:0.2)AB:0.3,(C:0.4,D:0.1)CD:0.2)root;")
print(f"Number of leaves: {len(t.get_leaves())}")
print(f"Leaf names: {t.get_leaf_names()}")
print(f"Tree depth: {t.get_farthest_leaf()[1]:.3f}")
# Number of leaves: 4
# Leaf names: ['A', 'B', 'C', 'D']
# Tree depth: 0.700
t.show()  # Opens interactive viewer (requires PyQt5)

コア API

モジュール 1:ツリーの入出力(ツリーの解析とシリアライズ)

文字列またはファイルからツリーを読み込み、さまざまな形式で書き出します。

from ete3 import Tree, PhyloTree

# Parse Newick string (format 1 = standard Newick with support values)
t = Tree("((A:0.1,B:0.2)90:0.3,(C:0.4,D:0.1)85:0.2)root;", format=1)
print(f"Root children: {[n.name for n in t.children]}")

# Load from file
t_file = Tree("my_tree.nwk")

# Write Newick with internal names and supports
nwk_str = t.write(format=1)
print(f"Newick: {nwk_str}")

# Write to file
t.write(outfile="output_tree.nwk", format=0)
print("Saved output_tree.nwk")
from ete3 import PhyloTree

# Load PhyloXML tree (retains sequence annotations)
# pt = PhyloTree("my_phylo.xml", parser="phyloxml")

# Load NHX format (extended Newick with key=value annotations)
nhx = Tree("((A[&&NHX:S=human:D=Y],B[&&NHX:S=mouse:D=N]))")
for leaf in nhx.get_leaves():
    print(f"{leaf.name}: species={leaf.S}, duplication={leaf.D}")
# A: species=human, duplication=Y
# B: species=mouse, duplication=N
モジュール 2:ツリーの走査と検索

先行順、後行順、または幅優先の走査でノードをたどり、名前や属性で検索します。

from ete3 import Tree

t = Tree("((Homo_sapiens:0.1,Pan_troglodytes:0.05)Hominidae:0.2,(Mus_musculus:0.3,Rattus_norvegicus:0.25)Muridae:0.4)Euarchontoglires;")

# Iterate all nodes (preorder by default)
for node in t.traverse("preorder"):
    depth = node.get_distance(t)
    print(f"{'leaf' if node.is_leaf() else 'internal'}: {node.name or 'unnamed'} depth={depth:.3f}")

# Search by name
human = t.search_nodes(name="Homo_sapiens")[0]
print(f"Human branch length: {human.dist:.3f}")
print(f"Ancestors: {[a.name for a in human.get_ancestors()]}")
from ete3 import Tree

t = Tree("((Homo_sapiens:0.1,Pan_troglodytes:0.05)Hominidae:0.2,(Mus_musculus:0.3,Rattus_norvegicus:0.25)Muridae:0.4)Euarchontoglires;")

# Lowest common ancestor (LCA) query
human = t & "Homo_sapiens"   # shorthand for search_nodes(name=...)[0]
mouse = t & "Mus_musculus"
lca = t.get_common_ancestor(human, mouse)
print(f"LCA of human and mouse: {lca.name}")
# LCA of human and mouse: Euarchontoglires

# Check monophyly
is_mono, mono_type, broken = t.check_monophyly(
    values=["Homo_sapiens", "Pan_troglodytes"], target_attr="name"
)
print(f"Hominids monophyletic: {is_mono}, type: {mono_type}")
# Hominids monophyletic: True, type: monophyletic
モジュール 3:ノードへの注釈付け

メタデータに基づく可視化や解析のために、ノードにカスタム属性を追加します。

from ete3 import Tree

t = Tree("((Homo_sapiens,Pan_troglodytes)Hominidae,(Mus_musculus,Rattus_norvegicus)Muridae)Euarchontoglires;")

# Annotate leaves with arbitrary metadata
metadata = {
    "Homo_sapiens":      {"genome_size_gb": 3.2, "ploidy": 2, "color": "blue"},
    "Pan_troglodytes":   {"genome_size_gb": 3.1, "ploidy": 2, "color": "green"},
    "Mus_musculus":      {"genome_size_gb": 2.7, "ploidy": 2, "color": "orange"},
    "Rattus_norvegicus": {"genome_size_gb": 2.9, "ploidy": 2, "color": "red"},
}
for leaf in t.get_leaves():
    for attr, val in metadata[leaf.name].items():
        setattr(leaf, attr, val)

# Access annotations
for leaf in t.get_leaves():
    print(f"{leaf.name}: {leaf.genome_size_gb} Gb, {leaf.color}")
from ete3 import Tree
import pandas as pd

t = Tree("((A,B)AB,(C,D)CD)root;")

# Load annotations from a DataFrame and apply to tree
df = pd.DataFrame({
    "name":  ["A", "B", "C", "D"],
    "value": [1.2, 3.4, 0.8, 2.1],
    "group": ["x", "x", "y", "y"],
})
name_to_row = df.set_index("name").to_dict(orient="index")

for leaf in t.get_leaves():
    if leaf.name in name_to_row:
        leaf.add_features(**name_to_row[leaf.name])
        print(f"{leaf.name}: value={leaf.value}, group={leaf.group}")
モジュール 4:ツリーの操作

ツリーの刈り込み、再ルート化、ウルトラメトリック化を行い、距離を計算します。

from ete3 import Tree

t = Tree("((A:0.1,B:0.2)AB:0.3,(C:0.4,D:0.1,(E:0.2,F:0.3)EF:0.1)CD:0.2)root;")
print(f"Original leaves: {t.get_leaf_names()}")

# Prune to a subset of taxa
t.prune(["A", "C", "E"], preserve_branch_length=True)
print(f"Pruned leaves: {t.get_leaf_names()}")

# Reroot on midpoint
t2 = Tree("((A:0.5,B:0.1):0.2,(C:0.3,D:0.4):0.1);")
midpoint_node, midpoint_dist = t2.get_midpoint_outgroup()
t2.set_outgroup(midpoint_node)
print(f"Rerooted at midpoint; root children: {[n.name for n in t2.children]}")

# Robinson-Foulds distance between two topologies
t_ref = Tree("((A,B),(C,D));")
t_alt = Tree("((A,C),(B,D));")
rf, rf_max, common_attrs, discard_t1, discard_t2, parts1, parts2 = t_ref.robinson_foulds(t_alt)
print(f"RF distance: {rf}, normalized: {rf/rf_max:.3f}")
モジュール 5:ツリーの可視化(TreeStyle/NodeStyle)

カスタムスタイルで出版品質のツリー図を描画します。

from ete3 import Tree, TreeStyle, NodeStyle, faces, AttrFace, CircleFace

t = Tree("((Homo_sapiens,Pan_troglodytes)Hominidae,(Mus_musculus,Rattus_norvegicus)Muridae)Euarchontoglires;")

# Define node styles
for node in t.traverse():
    nstyle = NodeStyle()
    if node.is_leaf():
        nstyle["shape"] = "circle"
        nstyle["size"] = 8
        nstyle["fgcolor"] = "darkblue"
    else:
        nstyle["shape"] = "sphere"
        nstyle["size"] = 6
        nstyle["fgcolor"] = "gray"
    node.set_style(nstyle)

# Add text face to leaves
for leaf in t.get_leaves():
    name_face = AttrFace("name", fsize=12, fgcolor="black")
    leaf.add_face(name_face, column=0, position="branch-right")

# Configure TreeStyle
ts = TreeStyle()
ts.mode = "r"          # rectangular (use "c" for circular)
ts.show_leaf_name = False
ts.branch_vertical_margin = 15
ts.title.add_face(faces.TextFace("Phylogenetic Tree", fsize=16), column=0)

# Render to file (no display needed)
t.render("tree_figure.png", tree_style=ts, w=800, units="px")
print("Saved tree_figure.png")
from ete3 import Tree, TreeStyle, NodeStyle, faces, RectFace

t = Tree("((A,B)AB,(C,D)CD)root;")

# Circular cladogram with colored rectangles
metadata = {"A": "red", "B": "red", "C": "blue", "D": "blue"}
for leaf in t.get_leaves():
    leaf.color = metadata[leaf.name]
    leaf.add_face(RectFace(width=20, height=20, fgcolor=leaf.color, bgcolor=leaf.color),
                  column=0, position="aligned")

ts = TreeStyle()
ts.mode = "c"          # circular layout
ts.arc_start = -180
ts.arc_span = 359
ts.show_leaf_name = True

t.render("circular_tree.png", tree_style=ts, w=600, units="px")
print("Saved circular_tree.png")
モジュール 6:NCBI Taxonomy との連携

種を NCBI taxonomy に対応付け、系統情報を取得し、分類ツリーを構築します。

from ete3 import NCBITaxa

# Initialize (downloads ~50 MB taxonomy DB on first call)
ncbi = NCBITaxa()
# ncbi.update_taxonomy_database()  # Refresh to latest NCBI taxonomy

# Name → taxid
taxid_map = ncbi.get_name_translator(["Homo sapiens", "Mus musculus", "Danio rerio"])
print(f"Taxid map: {taxid_map}")
# Taxid map: {'Homo sapiens': [9606], 'Mus musculus': [10090], 'Danio rerio': [7955]}

# Taxid → lineage
lineage = ncbi.get_lineage(9606)
names = ncbi.get_taxid_translator(lineage)
ranks = ncbi.get_rank(lineage)
for taxid in lineage[-6:]:
    print(f"  {ranks[taxid]:15s}: {names[taxid]}")
from ete3 import NCBITaxa, Tree, TreeStyle

ncbi = NCBITaxa()

# Build a taxonomy tree for a set of taxids
taxids = [9606, 10090, 7955, 6239, 7227]   # human, mouse, zebrafish, C. elegans, fruit fly
tree = ncbi.get_topology(taxids, intermediate_nodes=True)

# Annotate with common names
translator = ncbi.get_taxid_translator([int(n.name) for n in tree.get_leaves()])
for leaf in tree.get_leaves():
    leaf.sci_name = translator.get(int(leaf.name), leaf.name)
    print(f"Taxid {leaf.name}: {leaf.sci_name}")

# Render taxonomy tree
ts = TreeStyle()
ts.show_leaf_name = True
tree.render("taxonomy_tree.png", tree_style=ts, w=600, units="px")
print("Saved taxonomy_tree.png")
モジュール 7:比較ゲノミクス向け PhyloTree

重複/種分化イベントを遺伝子ツリーに注釈付けし、オーソログ関係をクエリします。

from ete3 import PhyloTree

# Build a gene tree with species mapping
# Format: leaf names must follow "gene_SPECIES" or use sp_naming_function
nwk = "((Hsap_BRCA1:0.1,Ptro_BRCA1:0.05)0.99:0.2,(Mmus_Brca1:0.3,Rnor_Brca1:0.25)0.95:0.1);"
t = PhyloTree(nwk, sp_naming_function=lambda name: name.split("_")[0])

# Annotate events (duplication vs speciation)
t.get_descendant_evol_events()

# Report events per node
for node in t.traverse():
    if not node.is_leaf() and hasattr(node, "evoltype"):
        print(f"Node evoltype: {node.evoltype} "
              f"(D=duplication, S=speciation)")

# Get orthologs for a given leaf
leaf = t & "Hsap_BRCA1"
orthologs = leaf.get_sisters()
print(f"Orthologs of Hsap_BRCA1: {[n.name for n in t.get_leaves() if n != leaf]}")

主要な概念

Newick 形式のバリエーション

ETE3 の format パラメーターは、解析する Newick の種類を指定します。

形式内部ノードのラベル枝長主な用途
0柔軟ありIQ-TREE、RAxML の出力
1名前+サポート値あり標準的な注釈付きツリー
5内部ノード名のみなしトポロジーのみのツリー
9葉の名前のみありシンプルなラベル付きツリー
100名前なしなしトポロジーのみ
from ete3 import Tree
# RAxML output (bootstrap values as internal labels)
t = Tree("((A:0.1,B:0.2)90:0.3,(C:0.4,D:0.1)85:0.2);", format=1)
for node in t.traverse():
    if not node.is_leaf():
        print(f"Support: {node.support}, dist: {node.dist}")

よくあるワークフロー

ワークフロー 1:アラインメント出力から注釈付きツリー図を作成する

目標:IQ-TREE の結果を読み込み、葉にメタデータを付けて、出版用の図を描画します。

from ete3 import Tree, TreeStyle, NodeStyle, AttrFace, faces
import pandas as pd

# Load IQ-TREE Newick output (format=1 handles support values)
t = Tree("iqtree_output.treefile", format=1)

# Midpoint rooting
outgroup, _ = t.get_midpoint_outgroup()
t.set_outgroup(outgroup)

# Load metadata table
meta = pd.read_csv("sample_metadata.csv")   # columns: name, clade, color
meta_dict = meta.set_index("name").to_dict(orient="index")

# Annotate leaves
for leaf in t.get_leaves():
    info = meta_dict.get(leaf.name, {})
    leaf.clade = info.get("clade", "unknown")
    leaf.face_color = info.get("color", "gray")

# Apply per-node styles
for node in t.traverse():
    ns = NodeStyle()
    if node.is_leaf():
        ns["size"] = 8
        ns["fgcolor"] = node.face_color if hasattr(node, "face_color") else "black"
    else:
        ns["size"] = 0   # hide internal nodes
    node.set_style(ns)

# Add name labels
for leaf in t.get_leaves():
    leaf.add_face(AttrFace("name", fsize=10), column=0, position="branch-right")
    leaf.add_face(AttrFace("clade", fsize=9, fgcolor="gray"), column=1, position="branch-right")

ts = TreeStyle()
ts.show_leaf_name = False
ts.branch_vertical_margin = 12
ts.scale = 200   # pixels per branch length unit

t.render("annotated_tree.pdf", tree_style=ts)
print("Saved annotated_tree.pdf")
ワークフロー 2:分類体系を考慮した種系統樹の構築

目標:NCBI taxid のリストからトポロジーが正しい種系統樹を構築し、Newick 形式でエクスポートします。

from ete3 import NCBITaxa, TreeStyle

ncbi = NCBITaxa()

# Input: list of NCBI taxids
taxids = [9606, 10090, 7955, 6239, 7227, 3702]  # human, mouse, zebrafish, worm, fly, Arabidopsis

# Build topology tree
species_tree = ncbi.get_topology(taxids, intermediate_nodes=False)

# Translate taxid leaf names to scientific names
translator = ncbi.get_taxid_translator([int(n.name) for n in species_tree.get_leaves()])
for leaf in species_tree.get_leaves():
    leaf.name = translator.get(int(leaf.name), leaf.name)

# Export Newick
nwk = species_tree.write(format=9)
print(f"Species tree Newick:\n{nwk}")
with open("species_tree.nwk", "w") as f:
    f.write(nwk)

# Render figure
ts = TreeStyle()
ts.show_leaf_name = True
ts.mode = "r"
species_tree.render("species_tree.png", tree_style=ts, w=800, units="px")
print("Saved species_tree.nwk and species_tree.png")
ワークフロー 3:Robinson-Foulds 距離の一括比較

目標:ブートストラップ反復樹のセットを参照トポロジーと比較します。

from ete3 import Tree
import pandas as pd

# Reference tree
ref_tree = Tree("reference.nwk", format=1)
ref_leaves = set(ref_tree.get_leaf_names())

results = []
for i, line in enumerate(open("bootstrap_trees.nwk")):
    bt = Tree(line.strip(), format=1)
    # Prune to common taxa
    common = ref_leaves & set(bt.get_leaf_names())
    ref_pruned = ref_tree.copy()
    bt_pruned = bt.copy()
    ref_pruned.prune(list(common))
    bt_pruned.prune(list(common))

    rf, rf_max, *_ = ref_pruned.robinson_foulds(bt_pruned, unrooted_trees=True)
    norm_rf = rf / rf_max if rf_max > 0 else 0
    results.append({"replicate": i + 1, "rf": rf, "rf_max": rf_max, "norm_rf": norm_rf})

df = pd.DataFrame(results)
print(df.describe())
df.to_csv("rf_distances.csv", index=False)
print(f"Mean normalized RF: {df['norm_rf'].mean():.4f}")

主なパラメーター

パラメーターモジュールデフォルト範囲/オプション効果
formatTree I/O00–9, 100Newick の形式。サポート値と内部名のどちらとして解析するかを制御します
quoted_node_namesTree I/OFalseTrue, Falseノード名に空白や特殊文字を使用できるようにします
preserve_branch_lengthPruningFalseTrue, Falseサブツリーの枝刈り時にパトリスティック距離を維持します
unrooted_treesRobinson-FouldsFalseTrue, False根なしトポロジーを比較します(ほとんどの遺伝子系統樹で必要です)
ts.modeTreeStyle"r""r", "c"矩形または円形のレイアウト
ts.scaleTreeStyleNone正の整数枝長の単位あたりのピクセル数。水平方向の広がりを制御します
ts.branch_vertical_marginTreeStyle5整数(px)葉の枝の間の垂直方向の間隔
intermediate_nodesNCBITaxaFalseTrue, Falseトポロジー樹に祖先の NCBI taxid を含めます

よく使われるレシピ

レシピ:クレード名に一致するすべてのサブツリーを抽出する

使用する場面:名前がパターンに一致するノードを根とするサブツリーをすべて特定します。

from ete3 import Tree

t = Tree("((Homo_sapiens,Pan_troglodytes)Hominidae,(Mus_musculus,Rattus_norvegicus)Muridae)Euarchontoglires;")

target_clade = "Hominidae"
nodes = t.search_nodes(name=target_clade)
for node in nodes:
    print(f"Clade {node.name}: {node.get_leaf_names()}")
    subtree_nwk = node.write(format=1)
    print(f"  Newick: {subtree_nwk}")
レシピ:非ウルトラメトリック系統樹をウルトラメトリック化する

使用する場面:ウルトラメトリックな入力を必要とする時間較正解析用に系統樹を準備します。

from ete3 import Tree

t = Tree("((A:0.3,B:0.1):0.4,(C:0.7,D:0.2):0.1);")
print(f"Before: max leaf distance = {max(t.get_distance(l) for l in t.get_leaves()):.4f}")

# Convert to ultrametric using ETE's method
t.convert_to_ultrametric()
dists = [t.get_distance(l) for l in t.get_leaves()]
print(f"After: all leaf distances = {set(round(d, 6) for d in dists)}")
レシピ:グループごとに葉を色分けして SVG をエクスポートする

使用する場面:手動でスタイルを設定せずに、プレゼンテーション用の色付き系統樹をすばやく作成します。

from ete3 import Tree, TreeStyle, NodeStyle

t = Tree("((A,B,C)GroupX,(D,E)GroupY,(F,G,H)GroupZ);")
group_colors = {"GroupX": "steelblue", "GroupY": "tomato", "GroupZ": "seagreen"}

for node in t.traverse():
    ns = NodeStyle()
    if node.is_leaf():
        parent_name = node.up.name if node.up else ""
        ns["fgcolor"] = group_colors.get(parent_name, "black")
        ns["size"] = 10
    node.set_style(ns)

ts = TreeStyle()
ts.show_leaf_name = True
ts.branch_vertical_margin = 14
t.render("colored_tree.svg", tree_style=ts, w=600, units="px")
print("Saved colored_tree.svg")

期待される出力

  • 系統樹オブジェクト:Tree/PhyloTree インスタンス — .children、.up、.name、.dist、.support を持つ、たどることができるノード階層
  • Newick 文字列:t.write(format=N) で生成される、後続のツールで使用する標準テキスト
  • 画像ファイル:t.render() で生成される .png、.pdf、.svg — 解像度は w パラメーターと dpi で制御します
  • 分類体系樹:NCBITaxa.get_topology() は、ノード名に taxid を使用した Tree を返します
  • RF 距離:robinson_foulds() が返す整数の生 RF 距離と整数の最大 RF 距離。rf / rf_max で正規化します

トラブルシューティング

問題原因解決策
NewickError: Unexepected charNewick 形式の不一致(サポート値フィールドと名前フィールド)format=0、1、または 5 を試してください。内部ノードにサポート値または名前があるか確認してください
RuntimeError: cannot connect to displayPyQt5 でのレンダリングにはディスプレイが必要ですt.show() の代わりに t.render("out.png", ...) を使用してください。ヘッドレスサーバーでは、xvfb-run の下で実行してください
AttributeError: 'Tree' object has no attributeノードのフィーチャーが注釈されていませんdir(node) を確認するか、アクセス前に hasattr(node, "attr") を使用してください
NCBI 分類体系データベースが見つからない初回使用時で、データベースがダウンロードされていませんNCBITaxa().update_taxonomy_database() を一度呼び出してください
系統樹の図ですべての葉が重なっている枝長がすべてゼロで、scale の設定が小さすぎますts.scale = None にして自動スケーリングするか、ts.scale の値を大きくしてください
robinson_foulds で ValueError が発生する系統樹に共通する葉がありません比較する前に、両方の系統樹を共通の分類群セットに枝刈りしてください
大きな系統樹(葉が 500 個以上)のレンダリングが遅いノードごとに Python でレンダリングループを実行していますts.show_leaf_name = False にしてフェイスを最小限にしてください。Newick をエクスポートして FigTree で描画する方法も検討してください

参考資料

コメント