heattree_py
Interactive phylogenetic tree visualisation for Jupyter notebooks.
heattree-py embeds the JavaScript heat-tree
widget into Jupyter notebooks using IPython.display.HTML. The output is fully
self-contained and works in live Jupyter sessions and in offline HTML exports
(no running Python kernel required).
This is the Python counterpart of the R heattree package.
Installation
pip install heattree_py
Documentation
Full documentation with interactive examples is available at: https://grunwaldlab.github.io/heattree_py/
Quick start
from heattree_py import heat_tree
# Minimal example with a Newick string
heat_tree("(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);")
Usage
Tree input
heat_tree() accepts trees in any of the common Python formats:
# Newick string
heat_tree("(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);")
# Path to a Newick file
heat_tree("path/to/tree.nwk")
# ete3 TreeNode
from ete3 import Tree
tree = Tree("(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);")
heat_tree(tree)
# dendropy Tree
import dendropy
tree = dendropy.Tree.get(data="(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);", schema="newick")
heat_tree(tree)
# Biopython Phylo tree
from Bio import Phylo
from io import StringIO
tree = Phylo.read(StringIO("(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);"), "newick")
heat_tree(tree)
# scikit-bio TreeNode
import skbio
tree = skbio.TreeNode.read(StringIO("(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);"))
heat_tree(tree)
Metadata
Pass a pandas.DataFrame to colour or size tree elements by metadata
columns. The DataFrame must include a column whose values match node labels in
the tree (the JavaScript widget detects the matching column automatically).
import pandas as pd
from heattree_py import heat_tree
tree = "(A:0.1,B:0.2,(C:0.3,D:0.4):0.5);"
metadata = pd.DataFrame({
"node_id": ["A", "B", "C", "D"],
"group": ["x", "x", "y", "y"],
"size": [10, 20, 30, 40],
})
heat_tree(tree, metadata=metadata, aesthetics={"tipLabelColor": "group"})
If the DataFrame index contains node IDs (rather than a column), it is automatically included as a column and used for matching:
metadata = pd.DataFrame(
{"group": ["x", "x", "y", "y"]},
index=["A", "B", "C", "D"],
)
heat_tree(tree, metadata=metadata, aesthetics={"tipLabelColor": "group"})
File paths to TSV/CSV files are also accepted:
heat_tree("tree.nwk", metadata="metadata.tsv")
Aesthetics
The aesthetics parameter maps visual properties to metadata columns:
| Aesthetic | Description | Data type |
|---|---|---|
tipLabelText |
Text content of tip labels | any |
tipLabelColor |
Colour of tip labels | categorical/continuous |
tipLabelSize |
Size of tip labels | continuous |
tipLabelFont |
Font family for tip labels | categorical |
tipLabelStyle |
Font style (normal, bold, italic) | categorical |
heat_tree(
tree,
metadata=metadata,
aesthetics={
"tipLabelColor": "group",
"tipLabelSize": "size",
},
)
Widget options
Additional keyword arguments are forwarded to the JavaScript widget as configuration options:
heat_tree(
tree,
layout="circular", # "rectangular" (default) or "circular"
branchLengthScale=1.5, # scale factor for branch lengths
treeHeightScale=2.0, # scale factor for spacing between tips
transitionDuration=750, # animation duration in ms
)
See the heat-tree documentation for the full list of options.
Multiple trees
Pass a list of trees (and optionally matching lists of metadata and aesthetics) to initialise the widget with multiple trees:
heat_tree(
tree=["(A,B,(C,D));", "(E,F,(G,H));"],
metadata=[meta1, meta2],
aesthetics=[{"tipLabelColor": "group"}, None],
)
Widget sizing
heat_tree(tree, width="80%", height="600px")
How it works
heat_tree() generates a self-contained HTML document that loads the
@grunwaldlab/heat-tree
JavaScript library from a CDN and initialises the interactive widget. This
document is embedded in an <iframe> and returned as an
IPython.display.HTML object. The iframe approach ensures the JavaScript
executes correctly across all Jupyter front-ends (classic Notebook, JupyterLab,
VS Code, Google Colab) and in static HTML exports.
Development
pip install hatch
# Run all checks (lint + test)
hatch run all
# Run tests only
hatch run test
# Auto-fix lint/format issues
hatch run fix
License
MIT
Metadata
Release files for heattree-py 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| heattree_py-0.1.0.tar.gz | 55.1 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| heattree_py-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 134.2 kB
Release files / heattree_py-0.1.0.tar.gz
| Download URL | heattree_py-0.1.0.tar.gz |
|---|---|
| Size | 55.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e93bf2456da22a3eb3eef078fa2ca456c58bb1150fd01fb7bc31d3e85dc26832
|
|
BLAKE2b-256 checksum How to use checksums |
1854718b34307aa5baed00a8c563d591da21f17c5fa8b1d57e39b9f4e1e955d6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / heattree_py-0.1.0-py3-none-any.whl
| Download URL | heattree_py-0.1.0-py3-none-any.whl |
|---|---|
| Size | 79.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d3201bae64eaeb5f7b7004110a3c5700b4c335a2e074a49425a5a7cd9de3ed9a
|
|
BLAKE2b-256 checksum How to use checksums |
3934c8c15894c643159e4f44da5e0c03292697abdff7ae4e54e5a9319d594884
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Security for heattree-py 0.1.0
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.