BioSkills bio-phylo-tree-visualization
Draw and export phylogenetic trees using Biopython Bio.Phylo with matplotlib and modern alternatives. Use when creating tree figures, customizing colors and labels, exporting to image formats, or choosing between Bio.Phylo, ggtree, ETE4, and iTOL for publication.
git clone https://github.com/GPTomics/bioSkills
T=$(mktemp -d) && git clone --depth=1 https://github.com/GPTomics/bioSkills "$T" && mkdir -p ~/.claude/skills && cp -r "$T/phylogenetics/tree-visualization" ~/.claude/skills/gptomics-bioskills-bio-phylo-tree-visualization && rm -rf "$T"
phylogenetics/tree-visualization/SKILL.mdVersion Compatibility
Reference examples tested with: BioPython 1.83+, matplotlib 3.8+
Before using code patterns, verify installed versions match. If versions differ:
- Python:
thenpip show <package>
to check signatureshelp(module.function)
If code throws ImportError, AttributeError, or TypeError, introspect the installed package and adapt the example to match the actual API rather than retrying.
Tree Visualization
"Create a publication-quality tree figure" → Draw and customize phylogenetic tree visualizations with colored branches, tip labels, and bootstrap support values using matplotlib.
- Python:
with matplotlib customizationBio.Phylo.draw()
Draw phylogenetic trees using matplotlib integration. Bio.Phylo provides basic rectangular tree plots suitable for quick visualization. For publication-quality figures with complex annotations, circular layouts, or metadata heatmaps, consider the alternatives below.
Visualization Tool Decision
| Tool | Type | Best For | Limitations |
|---|---|---|---|
| Bio.Phylo + matplotlib | Python | Quick rectangular plots, scripted pipelines | No circular/radial layouts, limited annotation |
| ggtree (R/Bioconductor) | R | Publication figures with complex annotations, metadata heatmaps | Requires R |
| ETE4 (Python) | Python | Python-based pipelines, NCBI taxonomy integration, tree comparison | More complex API |
| iTOL v6 (web) | GUI | Rapid interactive visualization, large trees, collaboration | Requires upload; web-dependent |
| FigTree | Desktop | Quick inspection during analysis | No scripting |
For publication: ggtree (R) or ETE4 (Python) for reproducible, customizable figures. iTOL for rapid prototyping, then export SVG and refine in Illustrator/Inkscape.
For quick exploration: Bio.Phylo (below) or FigTree.
Key ggtree features:
%<+% operator connects metadata dataframes to the tree; geom_cladelabel() for clade bars; gheatmap() for aligned heatmaps; supports circular, fan, rectangular, unrooted layouts.
Tanglegrams (comparing two trees): R:
phytools::cophylo() or dendextend; Python: ETE4 tree comparison functions.
Required Import
from Bio import Phylo import matplotlib.pyplot as plt
ASCII Tree Display
tree = Phylo.read('tree.nwk', 'newick') # Quick text representation print(tree) # ASCII art diagram Phylo.draw_ascii(tree)
Basic Tree Drawing
tree = Phylo.read('tree.nwk', 'newick') # Simple plot (opens interactive window) Phylo.draw(tree) plt.show() # Save to file fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax) plt.savefig('tree.png', dpi=300, bbox_inches='tight') plt.close()
Customizing Tree Appearance
fig, ax = plt.subplots(figsize=(12, 10)) Phylo.draw(tree, axes=ax, do_show=False, branch_labels=lambda c: f'{c.branch_length:.2f}' if c.branch_length else '', label_func=lambda c: c.name if c.is_terminal() else '') ax.set_title('Phylogenetic Tree') plt.savefig('custom_tree.png', dpi=300, bbox_inches='tight') plt.close()
Label Customization
# Custom label function def custom_labels(clade): if clade.is_terminal(): return clade.name elif clade.confidence: return f'{clade.confidence:.0f}' return '' fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax, label_func=custom_labels) plt.savefig('labeled_tree.png', dpi=300) plt.close()
Branch Labels (Bootstrap, Lengths)
# Show branch lengths def branch_length_labels(clade): if clade.branch_length: return f'{clade.branch_length:.3f}' return '' fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax, branch_labels=branch_length_labels) plt.savefig('with_lengths.png', dpi=300) plt.close() # Show bootstrap values (stored in clade.confidence or clade.name for internal nodes) def bootstrap_labels(clade): if not clade.is_terminal() and clade.confidence: return f'{clade.confidence:.0f}' return '' Phylo.draw(tree, axes=ax, branch_labels=bootstrap_labels)
Coloring Trees
# Color specific clades before drawing tree = Phylo.read('tree.nwk', 'newick') # Set colors for specific clades (PhyloXML trees support this natively) for clade in tree.find_clades(): if clade.name and 'Human' in clade.name: clade.color = 'red' elif clade.name and 'Mouse' in clade.name: clade.color = 'blue' fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax) plt.savefig('colored_tree.png', dpi=300) plt.close()
Highlighting Clades
from Bio.Phylo.PhyloXML import BranchColor # Convert to PhyloXML for color support phyloxml_tree = tree.as_phyloxml() # Color a clade and its descendants target = phyloxml_tree.find_any(name='Human') if target: target.color = BranchColor.from_name('red') fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(phyloxml_tree, axes=ax) plt.savefig('highlighted.png', dpi=300) plt.close()
Multiple Output Formats
tree = Phylo.read('tree.nwk', 'newick') tree.ladderize() fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax, do_show=False) # PNG (raster, good for presentations) plt.savefig('tree.png', dpi=300, bbox_inches='tight') # PDF (vector, good for publications) plt.savefig('tree.pdf', bbox_inches='tight') # SVG (vector, good for web) plt.savefig('tree.svg', bbox_inches='tight') plt.close()
Figure Size and Layout
# Adjust figure size based on tree size n_taxa = len(tree.get_terminals()) height = max(8, n_taxa * 0.3) # Scale with number of taxa fig, ax = plt.subplots(figsize=(10, height)) Phylo.draw(tree, axes=ax, do_show=False) plt.tight_layout() plt.savefig('scaled_tree.png', dpi=300) plt.close()
Phylo.draw() Parameters
| Parameter | Type | Description |
|---|---|---|
| Tree | Tree object to draw |
| Axes | Matplotlib axes (optional) |
| callable | Function to generate tip labels |
| callable/dict | Function or dict for branch labels |
| bool | Call plt.show() automatically (default True) |
Pre-Processing for Better Visualization
tree = Phylo.read('tree.nwk', 'newick') # Ladderize for cleaner appearance tree.ladderize(reverse=True) # Set missing branch lengths to small value for clade in tree.find_clades(): if clade.branch_length is None: clade.branch_length = 0.001 fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax) plt.savefig('clean_tree.png', dpi=300) plt.close()
Side-by-Side Tree Comparison
tree1 = Phylo.read('tree1.nwk', 'newick') tree2 = Phylo.read('tree2.nwk', 'newick') fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(16, 8)) Phylo.draw(tree1, axes=ax1, do_show=False) ax1.set_title('Tree 1') Phylo.draw(tree2, axes=ax2, do_show=False) ax2.set_title('Tree 2') plt.tight_layout() plt.savefig('comparison.png', dpi=300) plt.close()
Hide Axis and Frame
fig, ax = plt.subplots(figsize=(10, 8)) Phylo.draw(tree, axes=ax, do_show=False) ax.axis('off') # Remove axis ax.set_frame_on(False) # Remove frame plt.savefig('clean_tree.png', dpi=300, bbox_inches='tight', transparent=True) plt.close()
Deprecated Functions
| Function | Status | Alternative |
|---|---|---|
| Removed (1.79) | Use for rectangular trees |
For radial (circular) tree layouts, use ggtree (R), ETE4, or iTOL. Bio.Phylo only supports rectangular layouts.
Common Issues
| Issue | Cause | Solution |
|---|---|---|
| Labels overlap | Too many taxa | Increase figure height |
| No branch lengths | Missing in file | Set defaults or use cladogram |
| Colors not showing | Wrong tree format | Convert to PhyloXML first |
| Figure not saving | | Set before savefig |
Related Skills
- tree-io - Read and write tree files
- tree-manipulation - Ladderize and reroot before visualization
- distance-calculations - Build trees from alignments for visualization
- modern-tree-inference - ML tree inference produces trees for visualization
- data-visualization/ggplot2-fundamentals - R-based visualization for ggtree users