Skill ETE Toolkit
Présentation
ETE (Environment for Tree Exploration) est une boîte à outils pour l'analyse phylogénétique et des arbres hiérarchiques. Manipulez les arbres, analysez les événements évolutifs, visualisez les résultats et intégrez-les aux bases de données biologiques pour la recherche phylogénomique et l'analyse de clustering.
Capacités principales
1. Manipulation et analyse d'arbres
Chargez, manipulez et analysez des structures d'arbres hiérarchiques avec support pour :
- Entrée/sortie d'arbres : Lire et écrire les formats Newick, NHX, PhyloXML et NeXML
- Parcours d'arbres : Parcourez les arbres selon des stratégies préorder, postorder ou levelorder
- Modification de topologie : Élaguez, enracinez, effondrez des nœuds, résolvez les polytomies
- Calculs de distances : Calculez les longueurs de branches et les distances topologiques entre nœuds
- Comparaison d'arbres : Calculez les distances de Robinson-Foulds et identifiez les différences topologiques
Modèles courants :
from ete3 import Tree
# Load tree from file
tree = Tree("tree.nw", format=1)
# Basic statistics
print(f"Leaves: {len(tree)}")
print(f"Total nodes: {len(list(tree.traverse()))}")
# Prune to taxa of interest
taxa_to_keep = ["species1", "species2", "species3"]
tree.prune(taxa_to_keep, preserve_branch_length=True)
# Midpoint root
midpoint = tree.get_midpoint_outgroup()
tree.set_outgroup(midpoint)
# Save modified tree
tree.write(outfile="rooted_tree.nw")
Utilisez scripts/tree_operations.py pour la manipulation d'arbres en ligne de commande :
# Display tree statistics
python scripts/tree_operations.py stats tree.nw
# Convert format
python scripts/tree_operations.py convert tree.nw output.nw --in-format 0 --out-format 1
# Reroot tree
python scripts/tree_operations.py reroot tree.nw rooted.nw --midpoint
# Prune to specific taxa
python scripts/tree_operations.py prune tree.nw pruned.nw --keep-taxa "sp1,sp2,sp3"
# Show ASCII visualization
python scripts/tree_operations.py ascii tree.nw
2. Analyse phylogénétique
Analysez les arbres de gènes avec détection des événements évolutifs :
- Intégration d'alignement de séquences : Reliez les arbres aux alignements de séquences multiples (FASTA, Phylip)
- Nommage d'espèces : Extraction automatique ou personnalisée d'espèces à partir de noms de gènes
- Événements évolutifs : Détectez les événements de duplication et de spéciation à l'aide du chevauchement d'espèces ou de la réconciliation d'arbres
- Détection d'orthologie : Identifiez les orthologues et paralogues en fonction des événements évolutifs
- Analyse de famille de gènes : Divisez les arbres par duplications, effondrez les expansions spécifiques à la lignée
Flux de travail pour l'analyse d'arbres de gènes :
from ete3 import PhyloTree
# Load gene tree with alignment
tree = PhyloTree("gene_tree.nw", alignment="alignment.fasta")
# Set species naming function
def get_species(gene_name):
return gene_name.split("_")[0]
tree.set_species_naming_function(get_species)
# Detect evolutionary events
events = tree.get_descendant_evol_events()
# Analyze events
for node in tree.traverse():
if hasattr(node, "evoltype"):
if node.evoltype == "D":
print(f"Duplication at {node.name}")
elif node.evoltype == "S":
print(f"Speciation at {node.name}")
# Extract ortholog groups
ortho_groups = tree.get_speciation_trees()
for i, ortho_tree in enumerate(ortho_groups):
ortho_tree.write(outfile=f"ortholog_group_{i}.nw")
Recherche d'orthologues et de paralogues :
# Find orthologs to query gene
query = tree & "species1_gene1"
orthologs = []
paralogs = []
for event in events:
if query in event.in_seqs:
if event.etype == "S":
orthologs.extend([s for s in event.out_seqs if s != query])
elif event.etype == "D":
paralogs.extend([s for s in event.out_seqs if s != query])
3. Intégration de la taxonomie NCBI
Intégrez les informations taxonomiques à partir de la base de données NCBI Taxonomy :
- Accès à la base de données : Téléchargement automatique et cache local de la taxonomie NCBI (~300 Mo)
- Traduction taxid/nom : Convertissez entre les identifiants taxonomiques et les noms scientifiques
- Récupération de lignée : Obtenez les lignées évolutives complètes
- Arbres de taxonomie : Construisez des arbres d'espèces reliant les taxa spécifiés
- Annotation d'arbre : Annotez automatiquement les arbres avec les informations taxonomiques
Construction d'arbres basés sur la taxonomie :
from ete3 import NCBITaxa
ncbi = NCBITaxa()
# Build tree from species names
species = ["Homo sapiens", "Pan troglodytes", "Mus musculus"]
name2taxid = ncbi.get_name_translator(species)
taxids = [name2taxid[sp][0] for sp in species]
# Get minimal tree connecting taxa
tree = ncbi.get_topology(taxids)
# Annotate nodes with taxonomy info
for node in tree.traverse():
if hasattr(node, "sci_name"):
print(f"{node.sci_name} - Rank: {node.rank} - TaxID: {node.taxid}")
Annotation d'arbres existants :
# Get taxonomy info for tree leaves
for leaf in tree:
species = extract_species_from_name(leaf.name)
taxid = ncbi.get_name_translator([species])[species][0]
# Get lineage
lineage = ncbi.get_lineage(taxid)
ranks = ncbi.get_rank(lineage)
names = ncbi.get_taxid_translator(lineage)
# Add to node
leaf.add_feature("taxid", taxid)
leaf.add_feature("lineage", [names[t] for t in lineage])
4. Visualisation d'arbre
Créez des visualisations d'arbre de qualité publication :
- Formats de sortie : PNG (raster), PDF et SVG (vecteur) pour les publications
- Modes de disposition : Dispositions rectangulaires et circulaires d'arbres
- GUI interactif : Explorez les arbres de manière interactive avec zoom, panoramique et recherche
- Style personnalisé : NodeStyle pour l'apparence des nœuds (couleurs, formes, tailles)
- Faces : Ajoutez des éléments graphiques (texte, images, graphiques, cartes thermiques) aux nœuds
- Fonctions de disposition : Style dynamique en fonction des propriétés des nœuds
Flux de travail de visualisation basique :
from ete3 import Tree, TreeStyle, NodeStyle
tree = Tree("tree.nw")
# Configure tree style
ts = TreeStyle()
ts.show_leaf_name = True
ts.show_branch_support = True
ts.scale = 50 # pixels per branch length unit
# Style nodes
for node in tree.traverse():
nstyle = NodeStyle()
if node.is_leaf():
nstyle["fgcolor"] = "blue"
nstyle["size"] = 8
else:
# Color by support
if node.support > 0.9:
nstyle["fgcolor"] = "darkgreen"
else:
nstyle["fgcolor"] = "red"
nstyle["size"] = 5
node.set_style(nstyle)
# Render to file
tree.render("tree.pdf", tree_style=ts)
tree.render("tree.png", w=800, h=600, units="px", dpi=300)
Utilisez scripts/quick_visualize.py pour une visualisation rapide :
# Basic visualization
python scripts/quick_visualize.py tree.nw output.pdf
# Circular layout with custom styling
python scripts/quick_visualize.py tree.nw output.pdf --mode c --color-by-support
# High-resolution PNG
python scripts/quick_visualize.py tree.nw output.png --width 1200 --height 800 --units px --dpi 300
# Custom title and styling
python scripts/quick_visualize.py tree.nw output.pdf --title "Species Phylogeny" --show-support
Visualisation avancée avec faces :
from ete3 import Tree, TreeStyle, TextFace, CircleFace
tree = Tree("tree.nw")
# Add features to nodes
for leaf in tree:
leaf.add_feature("habitat", "marine" if "fish" in leaf.name else "land")
# Layout function
def layout(node):
if node.is_leaf():
# Add colored circle
color = "blue" if node.habitat == "marine" else "green"
circle = CircleFace(radius=5, color=color)
node.add_face(circle, column=0, position="aligned")
# Add label
label = TextFace(node.name, fsize=10)
node.add_face(label, column=1, position="aligned")
ts = TreeStyle()
ts.layout_fn = layout
ts.show_leaf_name = False
tree.render("annotated_tree.pdf", tree_style=ts)
5. Analyse de clustering
Analysez les résultats de clustering hiérarchique avec intégration de données :
- ClusterTree : Classe spécialisée pour les dendrogrammes de clustering
- Liaison de matrice de données : Connectez les feuilles d'arbre aux profils numériques
- Métriques de cluster : Coefficient de silhouette, indice de Dunn, distances intra/inter-cluster
- Validation : Testez la qualité du cluster avec différentes métriques de distance
- Visualisation de carte thermique : Affichez les matrices de données aux côtés des arbres
Flux de travail de clustering :
from ete3 import ClusterTree
# Load tree with data matrix
matrix = """#Names\tSample1\tSample2\tSample3
Gene1\t1.5\t2.3\t0.8
Gene2\t0.9\t1.1\t1.8
Gene3\t2.1\t2.5\t0.5"""
tree = ClusterTree("((Gene1,Gene2),Gene3);", text_array=matrix)
# Evaluate cluster quality
for node in tree.traverse():
if not node.is_leaf():
silhouette = node.get_silhouette()
dunn = node.get_dunn()
print(f"Cluster: {node.name}")
print(f" Silhouette: {silhouette:.3f}")
print(f" Dunn index: {dunn:.3f}")
# Visualize with heatmap
tree.show("heatmap")
6. Comparaison d'arbre
Quantifiez les différences topologiques entre arbres :
- Distance de Robinson-Foulds : Métrique standard pour la comparaison d'arbres
- RF normalisé : Distance invariante en échelle (0,0 à 1,0)
- Analyse de partition : Identifiez les bipartitions uniques et partagées
- Arbres de consensus : Analysez le support sur plusieurs arbres
- Comparaison par lot : Comparez plusieurs arbres par paire
Comparez deux arbres :
from ete3 import Tree
tree1 = Tree("tree1.nw")
tree2 = Tree("tree2.nw")
# Calculate RF distance
rf, max_rf, common_leaves, parts_t1, parts_t2 = tree1.robinson_foulds(tree2)
print(f"RF distance: {rf}/{max_rf}")
print(f"Normalized RF: {rf/max_rf:.3f}")
print(f"Common leaves: {len(common_leaves)}")
# Find unique partitions
unique_t1 = parts_t1 - parts_t2
unique_t2 = parts_t2 - parts_t1
print(f"Unique to tree1: {len(unique_t1)}")
print(f"Unique to tree2: {len(unique_t2)}")
Comparez plusieurs arbres :
import numpy as np
trees = [Tree(f"tree{i}.nw") for i in range(4)]
# Create distance matrix
n = len(trees)
dist_matrix = np.zeros((n, n))
for i in range(n):
for j in range(i+1, n):
rf, max_rf, _, _, _ = trees[i].robinson_foulds(trees[j])
norm_rf = rf / max_rf if max_rf > 0 else 0
dist_matrix[i, j] = norm_rf
dist_matrix[j, i] = norm_rf
Installation et configuration
Installez la boîte à outils ETE :
# Basic installation
uv pip install ete3
# With external dependencies for rendering (optional but recommended)
# On macOS:
brew install qt@5
# On Ubuntu/Debian:
sudo apt-get install python3-pyqt5 python3-pyqt5.qtsvg
# For full features including GUI
uv pip install ete3[gui]
Configuration initiale de la taxonomie NCBI :
La première fois que NCBITaxa est instancié, il télécharge automatiquement la base de données de taxonomie NCBI (~300 Mo) vers ~/.etetoolkit/taxa.sqlite. Cela ne se produit qu'une fois :
from ete3 import NCBITaxa
ncbi = NCBITaxa() # Downloads database on first run
Mettez à jour la base de données de taxonomie :
ncbi.update_taxonomy_database() # Download latest NCBI data
Cas d'usage courants
Cas d'usage 1 : Pipeline phylogénomique
Flux de travail complet de l'arbre de gènes à l'identification des orthologues :
from ete3 import PhyloTree, NCBITaxa
# 1. Load gene tree with alignment
tree = PhyloTree("gene_tree.nw", alignment="alignment.fasta")
# 2. Configure species naming
tree.set_species_naming_function(lambda x: x.split("_")[0])
# 3. Detect evolutionary events
tree.get_descendant_evol_events()
# 4. Annotate with taxonomy
ncbi = NCBITaxa()
for leaf in tree:
if leaf.species in species_to_taxid:
taxid = species_to_taxid[leaf.species]
lineage = ncbi.get_lineage(taxid)
leaf.add_feature("lineage", lineage)
# 5. Extract ortholog groups
ortho_groups = tree.get_speciation_trees()
# 6. Save and visualize
for i, ortho in enumerate(ortho_groups):
ortho.write(outfile=f"ortho_{i}.nw")
Cas d'usage 2 : Prétraitement et formatage d'arbres
Traitez par lot les arbres pour l'analyse :
# Convert format
python scripts/tree_operations.py convert input.nw output.nw --in-format 0 --out-format 1
# Root at midpoint
python scripts/tree_operations.py reroot input.nw rooted.nw --midpoint
# Prune to focal taxa
python scripts/tree_operations.py prune rooted.nw pruned.nw --keep-taxa taxa_list.txt
# Get statistics
python scripts/tree_operations.py stats pruned.nw
Cas d'usage 3 : Figures de qualité publication
Créez des visualisations stylisées :
from ete3 import Tree, TreeStyle, NodeStyle, TextFace
tree = Tree("tree.nw")
# Define clade colors
clade_colors = {
"Mammals": "red",
"Birds": "blue",
"Fish": "green"
}
def layout(node):
# Highlight clades
if node.is_leaf():
for clade, color in clade_colors.items():
if clade in node.name:
nstyle = NodeStyle()
nstyle["fgcolor"] = color
nstyle["size"] = 8
node.set_style(nstyle)
else:
# Add support values
if node.support > 0.95:
support = TextFace(f"{node.support:.2f}", fsize=8)
node.add_face(support, column=0, position="branch-top")
ts = TreeStyle()
ts.layout_fn = layout
ts.show_scale = True
# Render for publication
tree.render("figure.pdf", w=200, units="mm", tree_style=ts)
tree.render("figure.svg", tree_style=ts) # Editable vector
Cas d'usage 4 : Analyse automatisée d'arbres
Traitez systématiquement plusieurs arbres :
from ete3 import Tree
import os
input_dir = "trees"
output_dir = "processed"
for filename in os.listdir(input_dir):
if filename.endswith(".nw"):
tree = Tree(os.path.join(input_dir, filename))
# Standardize: midpoint root, resolve polytomies
midpoint = tree.get_midpoint_outgroup()
tree.set_outgroup(midpoint)
tree.resolve_polytomy(recursive=True)
# Filter low support branches
for node in tree.traverse():
if hasattr(node, 'support') and node.support < 0.5:
if not node.is_leaf() and not node.is_root():
node.delete()
# Save processed tree
output_file = os.path.join(output_dir, f"processed_{filename}")
tree.write(outfile=output_file)
Documentation de référence
Pour une documentation API complète, des exemples de code et des guides détaillés, consultez les ressources suivantes dans le répertoire references/ :
api_reference.md: Documentation API complète pour toutes les classes et méthodes ETE (Tree, PhyloTree, ClusterTree, NCBITaxa), incluant les paramètres, les types de retour et les exemples de codeworkflows.md: Modèles de flux de travail courants organisés par tâche (opérations sur les arbres, analyse phylogénétique, comparaison d'arbres, intégration de taxonomie, analyse de clustering)visualization.md: Guide de visualisation complet couvrant TreeStyle, NodeStyle, Faces, fonctions de disposition et techniques de visualisation avancées
Chargez ces références lorsque des informations détaillées sont nécessaires :
# To use API reference
# Read references/api_reference.md for complete method signatures and parameters
# To implement workflows
# Read references/workflows.md for step-by-step workflow examples
# To create visualizations
# Read references/visualization.md for styling and rendering options
Dépannage
Erreurs d'importation :
# If "ModuleNotFoundError: No module named 'ete3'"
uv pip install ete3
# For GUI and rendering issues
uv pip install ete3[gui]
Problèmes de rendu :
Si tree.render() ou tree.show() échoue avec des erreurs liées à Qt, installez les dépendances système :
# macOS
brew install qt@5
# Ubuntu/Debian
sudo apt-get install python3-pyqt5 python3-pyqt5.qtsvg
Base de données NCBI Taxonomy :
Si le téléchargement de la base de données échoue ou devient corrompu :
from ete3 import NCBITaxa
ncbi = NCBITaxa()
ncbi.update_taxonomy_database() # Redownload database
Problèmes de mémoire avec les grands arbres :
Pour les très grands arbres (>10 000 feuilles), utilisez des itérateurs plutôt que des compréhensions de liste :
# Memory-efficient iteration
for leaf in tree.iter_leaves():
process(leaf)
# Instead of
for leaf in tree.get_leaves(): # Loads all into memory
process(leaf)
Référence du format Newick
ETE supporte plusieurs spécifications de format Newick (0-100) :
- Format 0 : Flexible avec longueurs de branches (par défaut)
- Format 1 : Avec noms de nœuds internes
- Format 2 : Avec valeurs de bootstrap/support
- Format 5 : Noms de nœuds internes + longueurs de branches
- Format 8 : Toutes les fonctionnalités (noms, distances, support)
- Format 9 : Noms de feuilles uniquement
- Format 100 : Topologie uniquement
Spécifiez le format lors de la lecture/écriture :
tree = Tree("tree.nw", format=1)
tree.write(outfile="output.nw", format=5)
Le format NHX (New Hampshire eXtended) préserve les fonctionnalités personnalisées :
tree.write(outfile="tree.nhx", features=["habitat", "temperature", "depth"])
Bonnes pratiques
- Préservez les longueurs de branches : Utilisez
preserve_branch_length=Truelors de l'élagage pour l'analyse phylogénétique - Contenu en cache : Utilisez
get_cached_content()pour l'accès répété au contenu des nœuds sur les grands arbres - Utilisez les itérateurs : Utilisez les méthodes
iter_*pour le traitement efficace des grands arbres en termes de mémoire - Choisissez un parcours approprié : Postorder pour l'analyse ascendante, preorder pour l'analyse descendante
- Validez la monophylie : Vérifiez toujours le type de clade renvoyé (monophylétique/paraphylétique/polyphylétique)
- Formats vectoriels pour publication : Utilisez PDF ou SVG pour les figures de publication (évolutifs, modifiables)
- Test interactif : Utilisez
tree.show()pour tester les visualisations avant de les rendre dans un fichier - PhyloTree pour la phylogénétique : Utilisez la classe PhyloTree pour les arbres de gènes et l'analyse évolutive
- Sélection de la méthode de copie : « newick » pour la vitesse, « cpickle » pour la fidélité complète, « deepcopy » pour les objets complexes
- Mise en cache des requêtes NCBI : Stockez les résultats des requêtes de taxonomie NCBI pour éviter les accès répétés à la base de données