etetoolkit について
ETE Toolkit(ETE3)は、系統樹の探索、編集、可視化を行う Python フレームワークです。進化生物学や比較ゲノム学のワークフロー向けに、複数の形式、NCBI 分類情報、柔軟な描画機能を備えています。
主な機能
- 01複数の系統樹形式の読み書き
- 02ノードの走査、検索、編集
- 03ノードへのメタデータ付与
- 04系統樹距離と進化統計の計算
- 05NCBI 分類情報の検索と樹の構築
- 06スタイルを調整した系統樹描画
活用シーン
- 01後続解析に向けた系統樹の整理と剪定
- 02メタデータ付き系統樹図の作成
- 03樹形比較や最終共通祖先の検索
- 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}")
主なパラメーター
| パラメーター | モジュール | デフォルト | 範囲/オプション | 効果 |
|---|---|---|---|---|
format | Tree I/O | 0 | 0–9, 100 | Newick の形式。サポート値と内部名のどちらとして解析するかを制御します |
quoted_node_names | Tree I/O | False | True, False | ノード名に空白や特殊文字を使用できるようにします |
preserve_branch_length | Pruning | False | True, False | サブツリーの枝刈り時にパトリスティック距離を維持します |
unrooted_trees | Robinson-Foulds | False | True, False | 根なしトポロジーを比較します(ほとんどの遺伝子系統樹で必要です) |
ts.mode | TreeStyle | "r" | "r", "c" | 矩形または円形のレイアウト |
ts.scale | TreeStyle | None | 正の整数 | 枝長の単位あたりのピクセル数。水平方向の広がりを制御します |
ts.branch_vertical_margin | TreeStyle | 5 | 整数(px) | 葉の枝の間の垂直方向の間隔 |
intermediate_nodes | NCBITaxa | False | True, 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 char | Newick 形式の不一致(サポート値フィールドと名前フィールド) | format=0、1、または 5 を試してください。内部ノードにサポート値または名前があるか確認してください |
RuntimeError: cannot connect to display | PyQt5 でのレンダリングにはディスプレイが必要です | 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 で描画する方法も検討してください |
参考資料
- ETE3 documentation — すべてのモジュールを網羅した公式チュートリアル
- ETE3 API reference — クラスとメソッドを網羅したリファレンス
- ETE3 GitHub repository — ソース、課題トラッカー、サンプルノートブック
- Huerta-Cepas J, Serra F, Bork P (2016) ETE 3: Reconstruction, Analysis, and Visualization of Phylogenomic Data. Mol Biol Evol 33:1635-1638 — ETE3 の主要な引用文献