Metadata-aware phylogenetic tree analysis and rendering engine
Project description
PieTree
Metadata-aware phylogenetic tree analysis and visualization for Python.
"Work with trees the way you think about them."
Features
🌳 Flexible Tree Building - Parse Newick, NEXUS, PhyloXML, or build programmatically
📊 Metadata-First Design - Attach arbitrary data to any node
🔍 Powerful Queries - Find clades, filter by metadata, compute distances
🎨 Rich Styling - CSS-like rules, highlighting, custom layouts
📈 Multiple Layouts - Phylogram, cladogram, ultrametric views
🖼️ Publication Quality - SVG vector or high-res PNG/PDF output
💻 CLI Tools - Complete command-line interface for workflows
✅ Well-Tested - 111 tests, comprehensive coverage
Installation
From PyPI
pip install pietree
From Source
git clone https://github.com/PedroCts/pietree.git
cd pietree
pip install -e .
Requirements
- Python 3.10+
- numpy, pandas, biopython, cairosvg
Quick Start
Python API
import pandas as pd
from pietree import parse_newick
# Load and annotate tree
tree = parse_newick("data/spiders.newick")
samples = pd.read_csv("data/spider_samples.csv", sep=";")
tree.annotate(samples, on="mitogenome_id")
# Style and query
tree.nodes(group="this_study").style(fill="red", radius=5)
tree.tip_labels(group="this_study").suffix(" *").style(font_weight="bold")
tree.metadata("taxonomy").highlight(depth=9, label_position="center_right", palette="tab10")
tree.metadata("taxonomy").label_nodes(show_duplicates=False)
tree.metadata("group").highlight(
values=["this_study"],
label="This study",
colors={"this_study": "#7e7e7e"},
label_position="center_right",
)
tree.metadata("group").panel(values=["Outgroup"])
tree.savefig("spiders_tree.svg")
Why PieTree?
Most phylogenetic libraries focus on either tree manipulation or tree rendering. PieTree focuses on the connection between the two — and on how metadata bridges them.
The typical workflow elsewhere looks like this: parse the tree, traverse nodes manually, extract tips for a clade of interest, compute the MRCA, pass coordinates to a plotting library, manually style elements. That's a lot of steps before anything biological is expressed.
In PieTree, the same workflow is:
tree.clade_by_taxon("Mammalia").highlight(fill="lightblue")
The clade is inferred from hierarchical metadata via longest-common-prefix, styled, and registered for rendering — in one call.
Core Concepts
The Rendering Pipeline
flowchart LR
A[PieTree] -->|to_render_spec| B[RenderSpec]
B -->|build_layout| C[Coordinates]
C --> D[RenderContext]
D --> L1[Background]
D --> L2[Highlights]
D --> L3[Branches]
D --> L4[Nodes]
D --> L5[Labels]
D --> L6[Panels]
D --> L7[Scale bar]
L1 & L2 & L3 & L4 & L5 & L6 & L7 --> SVG[SVG]
Layers are composited in order. Highlights render before branches and nodes so they sit underneath the tree. Each layer reads from RenderContext — a single source of truth for positions, options, registry state, and registered highlights.
Key Features
Metadata-First Annotation
Annotate from a DataFrame by any join key — not just node names:
tree.annotate(samples, on="mitogenome_id")
Metadata is stored on each node as a PieMeta mapping and is available throughout the query and render pipeline.
Hierarchical Inference
When metadata is stored as lists representing taxonomic paths (e.g. ["Animalia", "Arthropoda", "Insecta"]), PieTree can infer the value for any internal node via longest-common-prefix across its descendant tips — without modifying the tree.
tree.metadata("taxonomy").infer() # → {node_id: [inferred, path], ...}
This inference drives both .highlight() and .label_nodes() automatically.
Fluent Querying
tree.nodes(group="this_study") # NodeSelection
tree.tips # NodeSelection (all tips)
tree.tip_labels(country="Brazil") # LabelSelection
tree.branches() # BranchSelection
Selections support chained styling, renaming, suffixing, and highlighting.
Clade Highlights
Highlight clades manually or automatically from metadata:
# Manual
tree.clade(["Tip_A", "Tip_B"]).highlight(fill="#4e79a7", label="Clade I")
# From metadata — one highlight per distinct taxon at depth 1
tree.metadata("taxonomy").highlight(depth=1, palette="set2")
Metadata Panels
Side panels display categorical metadata as grouped bars alongside the tree, automatically positioned after tip labels:
tree.metadata("group").panel(values=["Outgroup"])
Layout Modes
tree.savefig("tree.svg", mode="phylogram") # branch-length proportional
tree.savefig("tree.png", mode="cladogram") # equal branch lengths, PNG format
tree.savefig("tree.pdf", mode="ultrametric") # tips aligned to present, PDF format
Philosophy
PieTree is built on three principles.
Biological semantics. The API should reflect how biologists think about trees — in terms of clades, taxa, metadata fields, and study groups — not graph traversals and coordinate systems. tree.clade_by_taxon("Insecta") is a biological statement; it should work directly.
Metadata as topology. In most analyses, what matters is not just the shape of the tree but what the tips represent. PieTree treats metadata as a first-class component of the tree object, queryable, inferred, and renderable with the same fluency as topology.
Fluent, composable operations. Every operation returns something you can act on further. Selections can be styled, labeled, highlighted. Views can be highlighted, paneled, or iterated. The pipeline from data to publication figure should read like a description of the figure itself.
Roadmap
Current
- Newick I/O (read and write)
- Hierarchical metadata inference (longest-common-prefix)
- Automatic clade highlighting from metadata
- Metadata side panels
- Fluent node / branch / label selections
- Phylogram, cladogram, and ultrametric layouts
- Horizontal and vertical orientations
- SVG rendering with layered pipeline
- Scale bar
- Style engine with per-node overrides
Planned
- Interactive HTML export
- CLI interface
- Comparative / tanglegram layouts
- Additional annotation geometry (arrows, brackets, icons)
- Analysis modules (diversity, patristic distances, ancestral state)
Contributing
Contributions, bug reports, and feature requests are welcome. If you have ideas for new phylogenetic analyses, visualization styles, or metadata workflows, open an issue or pull request.
License
MIT License.
Render tree (format auto-detected from extension)
tree.savefig("tree.svg", mode="phylogram")
### Command Line
```bash
# Validate tree structure
pietree validate tree.newick
# Render to SVG
pietree render tree.newick -o tree.svg -m cladogram
# Query nodes
pietree query tree.newick "tips" -o json
# Annotate with metadata
pietree annotate tree.newick metadata.csv -o annotated.newick
# Convert formats
pietree convert tree.nex tree.newick
Documentation
- Documentation Home - Getting started
- User Guide - Detailed tutorials
- API Reference - Complete API docs
- CLI Reference - Command-line tools
- Contributing - Development guidelines
Examples
See the examples/ directory for complete working examples:
- Basic Tree - Simple tree visualization
- Metadata Annotation - Adding and using metadata
- Spiders - Real phylogenetic analysis with styling
- Insects - Complex tree with multiple metadata fields
Architecture
PieTree is organized into focused modules:
pietree/
├── core/ # Base abstractions
├── tree/ # Tree structure and operations
├── metadata/ # Metadata system
├── query/ # Selection API
├── style/ # Styling engine
├── render/ # Rendering pipeline
├── io/ # File I/O (Newick, NEXUS, etc.)
└── cli/ # Command-line interface
Key design principles:
- Mixin architecture for extensibility
- Metadata as first-class citizen
- Lazy evaluation for performance
- Abstract base classes for plugins
Project Status
Current Version: 0.1.0b (beta)
Status: Active development
Roadmap
- Additional file formats (BEAST, MrBayes)
- Interactive visualizations
- Performance optimization
- Standalone application
- GUI support
Contributing
We welcome contributions! Please see CONTRIBUTING.md for:
- Development setup
- Code standards
- Testing guidelines
- Pull request process
Quick start for contributors:
# Clone and setup
git clone https://github.com/PedroCts/pietree.git
cd pietree
pip install -e .
pip install pytest pytest-cov
# Run tests
pytest
# Check coverage
pytest --cov=pietree --cov-report=html
Citation
If you use PieTree in your research, please cite:
@software{pietree,
author = {Pedro Côrtes},
title = {PieTree: Metadata-aware phylogenetic tree visualization},
year = {2026},
url = {https://github.com/PedroCts/pietree}
}
License
MIT License - see LICENSE for details.
Acknowledgments
Built with ❤️ by Pedro Côrtes
PieTree - Work with phylogenetic trees the way you think about them.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pietree-0.1.0b0.tar.gz.
File metadata
- Download URL: pietree-0.1.0b0.tar.gz
- Upload date:
- Size: 78.5 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4dbe3d804c17aceb62c134b3765d01aa890dded416fc2842abe80e6f3c7ed708
|
|
| MD5 |
ea4ac7341196a6890c33096f795b8576
|
|
| BLAKE2b-256 |
4736cff580aa59a0df924be82fec6ee66d06703246393e424272c8f3e1cc4f7a
|
Provenance
The following attestation bundles were made for pietree-0.1.0b0.tar.gz:
Publisher:
publish.yaml on PedroCts/PieTree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pietree-0.1.0b0.tar.gz -
Subject digest:
4dbe3d804c17aceb62c134b3765d01aa890dded416fc2842abe80e6f3c7ed708 - Sigstore transparency entry: 1783843334
- Sigstore integration time:
-
Permalink:
PedroCts/PieTree@de1d72a274c36dfa9a5a1e7378027f65d5f1a82a -
Branch / Tag:
refs/tags/v0.1.0-beta - Owner: https://github.com/PedroCts
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@de1d72a274c36dfa9a5a1e7378027f65d5f1a82a -
Trigger Event:
release
-
Statement type:
File details
Details for the file pietree-0.1.0b0-py3-none-any.whl.
File metadata
- Download URL: pietree-0.1.0b0-py3-none-any.whl
- Upload date:
- Size: 94.7 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
12b2c99533fd1a60d39506c0acb8b6e2483deb508bb0839ad80ac3e55a9473b8
|
|
| MD5 |
ad915d48120fb0eda199a3d360df307f
|
|
| BLAKE2b-256 |
91a02f725a4d696455e90a68d4dd1e87840bd62fa2306d90f683b342ac16eec6
|
Provenance
The following attestation bundles were made for pietree-0.1.0b0-py3-none-any.whl:
Publisher:
publish.yaml on PedroCts/PieTree
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pietree-0.1.0b0-py3-none-any.whl -
Subject digest:
12b2c99533fd1a60d39506c0acb8b6e2483deb508bb0839ad80ac3e55a9473b8 - Sigstore transparency entry: 1783843626
- Sigstore integration time:
-
Permalink:
PedroCts/PieTree@de1d72a274c36dfa9a5a1e7378027f65d5f1a82a -
Branch / Tag:
refs/tags/v0.1.0-beta - Owner: https://github.com/PedroCts
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@de1d72a274c36dfa9a5a1e7378027f65d5f1a82a -
Trigger Event:
release
-
Statement type: