English | 中文
PyiTOL is a Python CLI tool for automating phylogenetic tree visualization on the iTOL (Interactive Tree Of Life) platform.
- 31 iTOL template types (plus
external-shape-bubble, a variant ofexternal-shape): color strips, heatmaps, bar charts, pie charts, symbols, binary matrices, gradients, protein domains, connections, and more - Full API client: upload, export PDF/SVG/PNG/TIFF/EPS/Newick/Nexus/PhyloXML, delete, and batch operations via iTOL batch endpoints
- Taxonomy & monophyly analysis: built-in dendropy integration for monophyletic/paraphyletic/polyphyletic group classification
- Extract taxonomy from tip names: supports GTDB (
d__Bacteria;p__Proteobacteria;...), embedded (_d_Bacteria_p_...), NCBI (Genus_species), auto-detection, underscore, and mixed formats - Monophyly check → conditional styling: check if a taxon is monophyletic, then automatically generate beautification templates
- Color-blind friendly palettes:
tol_bright,tol_vibrant,wong,okabeito, and more - Auto legend positioning: legends placed in bottom-right corner to avoid tree overlap
- Session snapshots & replay: YAML-based operation recording for reproducible workflows
- Newick/Nexus dual format: automatic tree file format detection
- Format A (embedded):
GB_GCA_0001_d_Bacteria_p_Proteo_c_..._g_Genus - Format B (semicolon):
d__Archaea;p__Thermoproteota;c__Korarchaeia;... - Mixed mode: auto-detect and unify both formats
- Extensible levels: custom taxonomy level prefixes via
--taxonomy-levels - Special identifiers:
LUCA(MRCA of all Bacteria and Archaea),LACA(MRCA of Archaea),LBCA(MRCA of Bacteria),ROOT(all tips in the tree)
# Collapse by taxon name (with monophyly check)
pyitol template create-collapse --taxon Cyanobacteriota --rank Phylum \
--taxonomy tax.csv --tree tree.nwk -o collapse.txt
# Strict mode: terminate on non-monophyletic groups
pyitol template create-collapse --taxon Proteobacteria --rank Phylum \
--taxonomy tax.csv --tree tree.nwk --strict -o collapse.txt
# Default mode: skip non-monophyletic groups and continue
pyitol template create-collapse --taxon Proteobacteria --rank Phylum \
--taxonomy tax.csv --tree tree.nwk -o collapse.txt- Stream output, no buffering, direct
sys.stdoutwrite withflush - ISO8601 timestamps:
2025-03-21T10:15:30.123 | INFO | message - Plain text format, no color output
--log-filefor simultaneous file output- Log levels:
DEBUG,INFO,WARNING,ERROR,CRITICAL
# Default: prompt user when multiple trees detected
pyitol template create color-strip --tree multi.nwk ...
# Specify processing strategy
pyitol template create color-strip --tree multi.nwk --multi-tree-mode first ...
pyitol template create color-strip --tree multi.nwk --multi-tree-mode last ...
pyitol template create color-strip --tree multi.nwk --multi-tree-mode random ...
pyitol template create color-strip --tree multi.nwk --multi-tree-mode split ...# Validate tree, sequence, and taxonomy files
pyitol validate --tree tree.nwk --taxonomy tax.csv --sequence seqs.fasta
# Deep validation: bracket balance, branch lengths, duplicate names, alphabet
pyitol validate --tree tree.nwk --alphabet DNAValidation includes:
- Trees: bracket balance, negative branch lengths (CRITICAL), empty names (ERROR), duplicate tips (ERROR), multi-root (CRITICAL)
- Sequences: alphabet detection (DNA/RNA/protein), ID uniqueness, length consistency
- Adversarial protection: malicious characters (control/bidi), circular dependencies, empty files
# Run self-test: verify dependencies, sample parsing, monophyly logic
pyitol self-testOutputs [PASS]/[FAIL] table verifying:
- Third-party dependency imports and versions
- Internal module imports
- Newick tree parsing
- Embedded taxonomy extraction
- Monophyly detection logic
- Malicious character detection
pip install pyitolWith conda (recommended for bioinformatics users):
conda create -n pyitol python=3.12
conda activate pyitol
pip install pyitolFrom source:
git clone https://github.com/ZengZichao/PyiTOL.git
cd PyiTOL
pip install -e ".[dev]"Install optional dependencies (memory monitoring):
pip install pyitol[memory]PyiTOL provides a Docker image for isolated environments:
# Build from the included Dockerfile
docker build -t pyitol:latest .
# Run with mounted data directory
docker run -v $(pwd)/data:/data pyitol:latest \
pyitol template create color-strip --tree /data/tree.nwk \
--taxonomy /data/tax.csv --column Phylum -o /data/output.txtThe Docker image includes all runtime dependencies and is suitable for HPC clusters or cloud platforms.
After installation, run the following commands to verify:
# Check version
pyitol --version
# Run self-test (verifies dependencies, sample parsing, core logic)
pyitol self-testExpected output:
pyitol 1.0.0
license: MIT
...
PyiTOL Self-Test Results
=======================================================
[PASS] Import typer (v0.25.1)
[PASS] Import pandas (v2.3.3)
[PASS] Parse sample Newick (4 tips)
[PASS] Monophyly detection (G1=mono, G2=mono)
...
All checks passed.
The fastest way to get started is to generate iTOL template files locally from your tree and taxonomy data — no API key or internet connection required:
# Generate a color-strip template from a Newick tree and taxonomy table
pyitol template create color-strip --tree tree.nwk --taxonomy tax.csv --column Phylum -o colorstrip.txtThis produces a plain-text iTOL template file (colorstrip.txt) that you can upload manually to iTOL via drag-and-drop.
Before generating templates, validate your input files for common issues:
pyitol validate --tree tree.nwk --taxonomy tax.csvThis checks tree format, bracket balance, duplicate tip names, and taxonomy consistency. For deeper validation including sequence alphabet detection:
pyitol validate --tree tree.nwk --taxonomy tax.csv --sequence seqs.fasta --alphabet DNA# Display version, Git hash, dependency versions and licenses
pyitol --versionOutput example:
pyitol 1.0.0
license: MIT
date: 2026-08-13
git: abc1234
dependencies:
typer: 0.25.1 (MIT)
pandas: 2.3.3 (BSD-3-Clause)
dendropy: 4.6.4 (BSD-3-Clause)
numpy: 2.4.4 (BSD-3-Clause)
...
The following steps require a free iTOL API key. If you only need local template generation, you can skip this section.
Three methods supported (highest to lowest priority):
# Method 1: Command-line (temporary)
pyitol task upload --tree tree.nwk --api-key YOUR_KEY
# Method 2: Environment variable
export ITOL_API_KEY=YOUR_KEY
# Method 3: Key file
pyitol task upload --tree tree.nwk --api-key-file /path/to/key.txtCredential security / 凭据安全
- Never commit key files to version control. Patterns
*.key,itolapi.key, and.itolapi.keyare already listed in.gitignore, but a key file can still leak through other channels — do not place it in cloud-synced folders (e.g. cloud-drive sync directories) or shared directories.- Prefer
~/.config/pyitol/(mode 600) or your system keychain for storing key files, rather than the project root.- Session snapshots and logs automatically redact key material (
***REDACTED***), so snapshots are safe to share.- If a key may have been exposed (committed, synced, or shared), rotate it immediately in your iTOL account settings.
# One-step: upload → render → export PDF locally
pyitol task upload-and-export \
--tree tree.nwk \
--config template1.txt \
--config template2.txt \
--api-key YOUR_KEY \
--dataset-name "MyTree" \
--format pdf \
--dpi 300 \
--output ./result.pdf \
--wait 30Supported formats: pdf, svg, png, tiff, eps, newick, nexus, phyloxml. Options: --dpi, --width, --height.
The upload-and-export command also supports --parameter for passing iTOL export parameters (e.g., datasets_visible, display_mode, background), consistent with the task export command:
# Control dataset visibility and rendering via --parameter
pyitol task upload-and-export \
--tree tree.nwk \
--config template1.txt --config template2.txt \
--api-key YOUR_KEY --dataset-name "MyTree" \
--format png --dpi 300 --output ./result.png --wait 30 \
--parameter datasets_visible=0,1 \
--parameter display_mode=2 \
--parameter background=ffffff# GTDB format: d__Bacteria;p__Proteobacteria;...;s__Escherichia_coli
pyitol taxonomy extract-from-names --tree tree.nwk --format gtdb -o taxonomy.csv
# Embedded format: GB_GCA_0001_d_Bacteria_p_Proteo_c_..._g_Genus
pyitol taxonomy extract-from-names --tree tree.nwk --format embedded -o taxonomy.csv
# NCBI format: Genus_species
pyitol taxonomy extract-from-names --tree tree.nwk --format ncbi -o taxonomy.csv
# Auto-detect format
pyitol taxonomy extract-from-names --tree tree.nwk --format auto -o taxonomy.csv
# Custom taxonomy levels
pyitol taxonomy extract-from-names --tree tree.nwk \
--taxonomy-levels "d:Domain,p:Phylum,c:Class,o:Order,f:Family,g:Genus,s:Species" \
-o taxonomy.csv# Check if Escherichia is monophyletic
# If yes → generate branch coloring template
# If no → warn and exit
pyitol taxonomy check-and-style \
--tree tree.nwk \
--taxonomy tax.csv \
--taxon Escherichia \
--rank Genus \
--action color-branch \
--color "#e41a1c" \
--output clade.txt
# Using special identifiers
pyitol taxonomy check-and-style \
--tree tree.nwk \
--taxonomy tax.csv \
--taxon LUCA \
--rank Domain \
--action color-branch \
--output luca.txt
# Without taxonomy file → auto-extract from tip names
pyitol taxonomy check-and-style \
--tree tree.nwk \
--taxon Salmonella \
--rank Genus \
--action highlight \
--output highlight.txtSupported styling types:
color-branch: branch coloringhighlight: label background highlightingcolor-strip: outer color strip
# Check monophyly of all genera
pyitol taxonomy monophyly --tree tree.nwk --taxonomy tax.csv \
--rank Genus --output monophyly_results.csv
# Check special identifiers
pyitol taxonomy monophyly --tree tree.nwk --taxonomy tax.csv \
--taxa LUCA,LACA,LBCA,ROOT --output special_monophyly.csv
# Extract taxonomy summary
pyitol taxonomy extract --tree tree.nwk --taxonomy tax.csv \
--rank Genus --output taxonomy_summary.csv
# List available taxonomy ranks
pyitol taxonomy ranks --taxonomy tax.csv# Color strip - categorical coloring by taxonomic rank (legend auto-positioned)
pyitol template create color-strip --tree tree.nwk --taxonomy tax.csv \
--column Phylum --palette tol_bright -o strip.txt
# Heatmap - numeric data visualization
pyitol template create heatmap --tree tree.nwk --taxonomy tax.csv \
--columns "gc_content,genome_size" --gradient "#ffffcc,#800026" -o heatmap.txt
# Bar chart - quantitative comparison
pyitol template create simple-bar --tree tree.nwk --taxonomy tax.csv \
--column genome_size --bar-color "#3c5484" -o bar.txt
# Binary matrix - presence/absence
pyitol template create binary --tree tree.nwk --taxonomy tax.csv \
--columns "amr_genes,virulence_factors" -o binary.txt
# Connection lines between nodes (JSON format)
pyitol template create connections --connections connections.json -o connections.txt
# Branch gradient - continuous coloring
pyitol template create branch-gradient --tree tree.nwk --taxonomy tax.csv \
--column gc_content --gradient "#313695,#a50026" -o gradient.txt
# Domain architecture
pyitol template create domains --data-file domains.json -o domain.txt
# Multi-column bubble external shape (numeric column visualization)
pyitol template create external-shape-bubble --tree tree.nwk --taxonomy tax.csv \
--columns "gc_content,genome_size,gene_count" -o bubble.txt
# Bundle multiple templates at once
pyitol template bundle --tree tree.nwk --taxonomy tax.csv \
--config '[{"type":"color-strip","column":"Phylum"},{"type":"heatmap","columns":"gc,genome_size"}]' \
--output-dir ./templates/PyiTOL generates plain text template files that can be directly uploaded to iTOL:
| Output Type | Format | Description |
|---|---|---|
Template files (.txt) |
iTOL standard | Contains dataset header and data rows, ready for iTOL |
Taxonomy table (.csv) |
CSV/TSV | ID column + taxonomy rank columns |
Monophyly results (.csv) |
CSV | Contains group/status/lca_node/member_count columns |
Session snapshots (.yaml) |
YAML | Operation history, supports replay |
Template file structure:
DATASET_COLORSTRIP
SEPARATOR TAB
DATASET_LABEL Phylum
COLOR #ff0000
...
DATA
TaxonA #4477AA Proteobacteria
TaxonB #EE6677 Firmicutes
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Input Files │ │ Taxonomy │ │ Templates │
│ │ │ Parsing │ │ Generation │
│ tree.nwk │────>│ From names │────>│ color-strip │
│ tax.csv │ │ or table │ │ heatmap │
│ seqs.fasta │ │ │ │ bar/pie/... │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
v v
┌─────────────┐ ┌─────────────┐
│ Monophyly │ │ Upload to │
│ Check │ │ iTOL │
│ │ │ │
│ monophyly │ │ upload │
│ check │ │ export PDF │
└─────────────┘ └─────────────┘
Typical workflow:
- Prepare input: Phylogenetic tree (Newick/Nexus) + taxonomy table (CSV/TSV)
- Parse taxonomy: Auto-extract from tip names or use external table
- Monophyly check: Verify if taxa are monophyletic
- Generate templates: Create iTOL visualization templates based on taxonomy
- Upload & export: Upload to iTOL platform and export PDF/SVG/PNG
| Palette | Colors | Source |
|---|---|---|
tol_bright |
#4477AA #EE6677 #228833 #CCBB44 #66CCEE #AA3377 #BBBBBB | Paul Tol |
tol_vibrant |
#EE7733 #0077BB #33BBEE #EE3377 #CC3311 #009988 #BBBBBB | Paul Tol |
wong |
#000000 #E69F00 #56B4E9 #009E73 #F0E442 #0072B2 #D55E00 #CC79A7 | Wong (2011) |
okabeito |
#E69F00 #56B4E9 #009E73 #F0E442 #0072B2 #D55E00 #CC79A7 #000000 | Okabe & Ito (2008) |
ibm |
#648FFF #785EF0 #DC267F #FE6100 #FFB000 | IBM Design |
Usage: --palette wong
# After a workflow, session snapshot is saved automatically
pyitol task upload --tree tree.nwk --config template.txt
# Snapshot saved to ~/.pyitol/session_logs/
# Replay a previous session
pyitol replay --session session.yaml
# Show suggested commands without executing
pyitol replay --session session.yaml --dry-run# Low memory mode (for large datasets)
pyitol --low-memory template create color-strip --tree large_tree.nwk ...
# Verbose logging (shows memory usage etc.)
pyitol --verbose template create color-strip --tree large_tree.nwk ...
# Log to file
pyitol --log-file pyitol.log template create color-strip --tree tree.nwk ...- Trees with >10,000 tips trigger INFO log about resource requirements
- Use
--verbosefor DEBUG-level memory usage (requirespsutil)
# Default: error if output file exists (all subcommands are now protected)
pyitol template create color-strip --tree tree.nwk -o output.txt
# Force overwrite (unified entry 'template create' only)
pyitol template create color-strip --tree tree.nwk -o output.txt --force
# Skip existing files (unified entry 'template create' only)
pyitol template create color-strip --tree tree.nwk -o output.txt --no-clobberAll standalone subcommands (e.g.,
create-color-strip,create-heatmap, etc.) now check if the output file already exists to prevent accidental overwrites. To overwrite, use the unified entrytemplate createwith--force.
Press Ctrl+C to gracefully terminate:
- Outputs current processing progress
- Closes all open file handles
- Deletes incomplete temporary files
- Exit code 130
| Exit Code | Meaning | Description |
|---|---|---|
| 0 | Success | Operation completed successfully |
| 1 | Runtime Error | Internal error, dependency issue, API failure |
| 2 | Parameter Error | Invalid CLI arguments, validation failure |
| 3 | Data Error | Input file format/content error |
| 130 | User Interrupt | SIGINT (Ctrl+C) received |
See Error Codes Documentation for details.
pyitol
├── --version Display version, Git hash and dependency versions
├── --verbose Enable verbose logging
├── --quiet Show only critical info
├── --log-file Log file path
├── --low-memory Low memory mode
├── self-test Run self-test
├── validate Validate input files
├── config Configuration file management
├── template Create and manage iTOL template files
│ ├── create-* 31 template creation subcommands
│ ├── create-collapse Collapse branches (with --taxon monophyly check)
│ ├── bundle Batch-generate multiple templates
│ └── validate Validate template format
├── taxonomy Taxonomy analysis & monophyly detection
│ ├── ranks List taxonomy ranks
│ ├── extract Extract taxonomy info
│ ├── extract-stats Extract taxonomy statistics
│ ├── extract-from-names Auto-extract taxonomy from tip names
│ ├── monophyly Monophyly check (supports LUCA/LACA/LBCA/ROOT)
│ ├── check-and-style Monophyly check → conditional styling
│ ├── style Taxonomy style templates
│ ├── convert-binary Convert to binary matrix
│ └── convert-connect Convert to connection pairs
├── task iTOL API task management
│ ├── upload Upload to iTOL
│ ├── export Export from iTOL
│ ├── upload-and-export Upload + export in one step
│ ├── delete Delete iTOL trees
│ ├── status Query tree status
│ └── run Batch task execution
├── tree Tree file operations
├── utils Utility tools
├── learn Reverse-learn from existing templates
└── replay Replay operation records
PyiTOL/
├── src/pyitol/ Source code
│ ├── api/ iTOL API client
│ ├── cli/ CLI command definitions
│ ├── core/ Core algorithms (parser, monophyly, taxonomy)
│ ├── templates/ Template generators and schema definitions
│ └── utils/ Utility functions (color, I/O, session, logging, shutdown)
├── tests/ Test suite (1702 tests)
│ ├── data/ Test data files
│ ├── core/ Core algorithm tests
│ ├── cli/ CLI command tests
│ ├── templates/ Template system tests
│ ├── utils/ Utility function tests
│ └── api/ API client tests
├── examples/
│ └── data/ Demo data files
├── docs/ Documentation
│ └── error_codes.md Error codes reference
├── benchmarks/ Performance benchmarks
└── pyproject.toml Project configuration
- Quick Start Guide
- Template Type Overview
- Taxonomy Analysis Tutorial
- CLI Reference
- API Guide
- Error Codes Reference
- Contributing
| Library | Version | License |
|---|---|---|
| typer | >=0.15.0 | MIT |
| rich | ~=13.0 | MIT |
| pandas | ~=2.0 | BSD-3-Clause |
| dendropy | ~=4.6 | BSD-3-Clause |
| numpy | >=1.24 | BSD-3-Clause |
| requests | ~=2.32 | Apache-2.0 |
| PyYAML | ~=6.0 | MIT |
| pydantic | ~=2.5 | MIT |
If you use PyiTOL in your research, please cite:
- PyiTOL: Zeng, Z. (2026). PyiTOL: reproducible Python workflows for iTOL annotation and taxonomic monophyly assessment. bioRxiv. doi:10.64898/2026.08.27.747471
- iTOL: Letunic, I., & Bork, P. (2021). Interactive Tree Of Life (iTOL) v5. Nucleic Acids Research, 49(W1), W293-W296. doi:10.1093/nar/gkab301
- DendroPy: Sukumaran, J., & Holder, M. T. (2010). DendroPy. Bioinformatics, 26(12), 1569-1571. doi:10.1093/bioinformatics/btq228
- DendroPy 5: Moreno, M. A., Holder, M. T., & Sukumaran, J. (2024). DendroPy 5: a mature Python library for phylogenetic computing. Journal of Open Source Software, 9(101), 6943. doi:10.21105/joss.06943
- itol.toolkit: Zhou, T., Xu, K., Zhao, F., Liu, W., Li, L., Hua, Z., & Zhou, X. (2023). itol.toolkit accelerates working with iTOL by an automated generation of annotation files. Bioinformatics, 39(6), btad339. doi:10.1093/bioinformatics/btad339
If you use the benchmark comparison features (ete3/ete4, optional dependencies):
- ETE 3: Huerta-Cepas, J., Serra, F., & Bork, P. (2016). ETE 3: Reconstruction, analysis, and visualization of phylogenomic data. Molecular Biology and Evolution, 33(6), 1635-1638. doi:10.1093/molbev/msw046
See CITATION.cff for machine-readable citation metadata.
- GitHub Issues: Report bugs or request features
- GitHub Discussions: Community discussions
- Email: zengzichao@sjtu.edu.cn
- Maintainer: Zichao Zeng
Feel free to reach out through the above channels for questions, suggestions, or contributions.
This project is licensed under the MIT License. See NOTICE for third-party copyright and license information.