Skip to main content

Interactive phylogenetic tree visualization for Jupyter notebooks using the heat-tree JavaScript widget

Project description

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

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

heattree_py-0.1.0.tar.gz (55.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

heattree_py-0.1.0-py3-none-any.whl (79.1 kB view details)

Uploaded Python 3

File details

Details for the file heattree_py-0.1.0.tar.gz.

File metadata

  • Download URL: heattree_py-0.1.0.tar.gz
  • Upload date:
  • Size: 55.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for heattree_py-0.1.0.tar.gz
Algorithm Hash digest
SHA256 e93bf2456da22a3eb3eef078fa2ca456c58bb1150fd01fb7bc31d3e85dc26832
MD5 eed3df31173a8218ac97e1936a94bde9
BLAKE2b-256 1854718b34307aa5baed00a8c563d591da21f17c5fa8b1d57e39b9f4e1e955d6

See more details on using hashes here.

File details

Details for the file heattree_py-0.1.0-py3-none-any.whl.

File metadata

  • Download URL: heattree_py-0.1.0-py3-none-any.whl
  • Upload date:
  • Size: 79.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.10.12

File hashes

Hashes for heattree_py-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d3201bae64eaeb5f7b7004110a3c5700b4c335a2e074a49425a5a7cd9de3ed9a
MD5 6d0debcaee68ef767a6b5f52293cda8d
BLAKE2b-256 3934c8c15894c643159e4f44da5e0c03292697abdff7ae4e54e5a9319d594884

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page