Skip to main content

Phylo3D-Trait: Deep-Time Macroevolutionary 3D Trait Visualization

PyPI Python 3.10+ License: MIT Latest Release CI WebGL2 OIT

Interactive 3D visualization of continuous trait evolution on phylogenetic trees.

Phylo3D-Trait is a Python CLI and library for mapping continuous phenotypic, physiological, morphological, genomic, or other quantitative traits onto phylogenetic trees in interactive 3D. For dated trees, evolutionary time is shown explicitly along the Z axis.

Input: a Newick/Nexus phylogeny plus CSV/TSV values for terminal and ancestral nodes.
Output: a standalone, offline-viewable WebGL2 HTML visualization combining phylogenetic topology, divergence time, continuous trait trajectories, ancestral-state estimates, interactive node inspection, and publication-quality PNG/SVG export.

Phylo3D-Trait is designed for macroevolution, phylogenetic comparative biology, continuous-trait evolution, ancestral-state visualization, and scientific 3D phylogenetic visualization. It visualizes supplied ancestral-state estimates; it does not infer phylogenies, date trees, or perform ancestral-state reconstruction (ASR). Results from workflows such as phytools::fastAnc(), ape::ace(), Brownian-motion models, or OU models can be supplied as node values.

Generates publication-oriented orthogonal rectangular phylograms with vertical curtain meshes. The recommended Four-Layer WebGL2 renderer uses bounded depth peeling for order-independent transparency while remaining self-contained in a single HTML file.

Phylo3D-Trait Interactive 3D Visualization (0.2 Transparency / Opacity 0.8)

Real-world macroevolutionary dataset (Eulipotyphla, 38 species) rendered with the Four-Layer WebGL2 engine at 0.2 transparency (--opacity 0.8), featuring adaptive front-facing axes and camera-aware outward labels.

🌐 Project site: https://hk20013106.github.io/Phylo3D-Trait/
📖 User & AI Agent Manual: docs/PHYLO3D_TRAIT_USAGE_GUIDE.md
🐛 Bug reports / feature requests: use GitHub Issues. Pull requests are welcome; see CONTRIBUTING.md.


1. Key Features & Architectural Innovations

  • 🚀 Dual Rendering Engines:
    • Fixed Four-Layer WebGL2 Depth Peeling (--renderer four-layer) (Recommended): Per-fragment Order-Independent Transparency (OIT) with zero external JavaScript dependencies (< 1 MB standalone HTML).
    • Classic Plotly Backend (--renderer plotly): Familiar Plotly.js 3D scene engine with extensive camera and layout controls.
  • 💎 True Order-Independent Transparency (OIT):
    • Bounded fragment depth peeling peels the nearest 4 curtain layers per pixel.
    • Omission transmittance error is mathematically bounded ($\le 0.81%$ at opacity 0.70; $\le 6.25%$ at opacity 0.50; $\le 0.16%$ at opacity 0.80).
    • Zero trace-sorting artifacts: Completely eliminates WebGL painter's algorithm sorting glitches, popping, and trace-clipping during 360° orbits.
  • 📐 Adaptive Front-Facing Scientific Axes (No Box Frame):
    • Clean open aesthetic: Obstructive 5-line 3D bounding box frames have been completely eliminated.
    • Dynamic front-corner tracking (frontAxisCorner): Numerical axes for Trait value ($Y$) and Time before present ($Z$, Ma) automatically anchor to the viewer-facing front corner across all azimuth (yaw) and elevation (pitch) angles.
    • Outward ticks & titles (outward2D): Axis ticks and labels always project outward into empty screen space, never penetrating or obscuring the phylogenetic tree.
  • 🏷️ Camera-Aware Species Label Anchoring:
    • Species labels dynamically detect the camera azimuth hemisphere (eyeX).
    • Automatically flips alignment between positive and negative $X$ hemispheres (translate(3px, -50%) vs translate(calc(-100% - 3px), -50%)), guaranteeing taxon names project outward from tips without invading tree branches.
  • 🔍 Interactive Node Picking & Ancestral Diagnostics:
    • Terminal Tips: Hover reveals Taxon name, Node ID, Trait value ($Y$), Evolutionary Time ($Z = 0$), and Tree Layout position ($X$).
    • Ancestral Internal Nodes: Hover reveals Clade hash ID, Ancestral Trait value ($Y$), Divergence Age ($Z$, Ma), Layout position ($X$), and descendant taxon summary.
    • Visual Guidance: High-contrast orange marker dot and dynamic vertical dashed projection line connecting nodes to the trait baseline.
  • 💾 Publication-Grade Export Toolbar:
    • Reset: Instantly restore default camera preset (yaw, pitch, zoom).
    • PNG Export: 2× Retina resolution raster export capturing curtains, centerlines, axes, labels, and colorbar into a crisp publication-ready image.
    • Hybrid SVG Export: Native SVG packaging the WebGL 4-layer depth-peeled curtain raster inside an <image> element, with all axes, tick marks, titles, species labels, and colorbar exported as lossless, editable vector graphics (<line>, <text>, <rect>).
  • 🔒 Deterministic Clade Identity:
    • Stable SHA-256 hash IDs for all ancestral nodes derived from alphabetically sorted descendant tip names (clade:<hash>).

Order-Independent Transparency (OIT): Opaque vs 0.2 Transparency

Opaque vs 0.2 Transparency Comparison

  • Left (Standard Opaque, --opacity 1.0): Foreground curtain walls completely occlude internal ancestral nodes, deeper clades, and branching topology.
  • Right (Four-Layer OIT, --opacity 0.8, 20% transparency): Fragment-level depth peeling renders deep-time ancestral lineages, intermediate clades, and trait shifts clearly visible through semi-transparent curtains without any trace-sorting artifacts or popping across 360° orbits.

2. Rendering Engines Comparison

Feature / Capability Four-Layer WebGL2 (--renderer four-layer) Classic Plotly (--renderer plotly)
Primary Use Case Publication figures, transparency, clean presentation Standard exploration, legacy workflows
Transparency Method Fragment-level Depth Peeling (4 layers OIT) Primitive-level Painter's Algorithm
Transparency Quality Glitch-free across 360° orbits, no popping Trace sorting / camera sorting required
HTML Bundle Size Ultra-lightweight (< 1 MB self-contained) Heavier (~3.5 MB with Plotly.js CDN/bundle)
JS Dependencies Zero external libraries (pure native WebGL2 + SVG) Requires Plotly.js runtime
Scientific Axes Adaptive Front-Corner tracking (Y & Z only, No Box Frame) Full 3D Cartesian Bounding Box
Interactive Hover Tips + Internal Nodes (descendants & vertical guide line) Tips only (Scatter3d markers)
Outward Label Flip Native dynamic camera-aware flip Plotly textposition anchor
Toolbar & Export Built-in Reset, 2× PNG, and Hybrid Vector/Raster SVG Plotly standard modebar snapshot

3. Scientific Coordinate System

The 3D space is mapped to an orthogonal rectangular phylogram:

Axis Scientific Meaning Description
$X$ Tree Layout Horizontal lineage separation ($0, 1, \dots, N-1$ at terminal tips; internal nodes positioned at children centroids).
$Y$ Trait Value ("Height") Trait value directly determines vertical elevation in 3D space. Low trait $\rightarrow$ low $Y$; high trait $\rightarrow$ high $Y$.
$Z$ Evolutionary Time Divergence age / time before present. Tips at $Z = 0$, internal nodes at $Z > 0$, root at $Z = \text{root_age}$ (Ma).

$$\text{Point}_k = (X_k, \text{Trait}_k, \text{Time}_k)$$

Coupling of Height and Color

  • Top branch geometry strictly obeys $Y = \text{Trait}$, and branch top lines are colored by the local trait value.
  • Curtain Mode branch (--curtain-color-mode branch): Vertically projects the local top branch trait color down each panel to the baseline. This removes artificial vertical gradients while preserving continuous evolutionary trait transitions along the branches.
  • Curtain Mode height (--curtain-color-mode height, default): Preserves the historical vertical gradient where vertex color intensity == vertex Y.
  • Independent Color Reversal (--reverse-colorscale): Reverses only the color palette lookup table without inverting trait heights or modifying scientific values.

4. Quickstart: 3-Step Reproducible Workflow

Step 1: Generate Node Values Template

Extract all tip names and canonical ancestral clade IDs from your tree:

python -m phylo3d_trait.cli template-values \
  --tree path/to/tree.nwk \
  --output path/to/node_values_template.csv

Step 2: Fill in Trait Values

Fill in the trait column with your measured tip values and reconstructed ancestral states:

node_id,trait
Species_A,1.25
Species_B,2.10
Species_C,3.85
Species_D,4.50
clade:b17c8419f544,1.64
clade:6a5756530335,4.10
clade:17f5f129f4c7,2.50

Step 3: Render Interactive 3D Visualization

Render an interactive 3D HTML visualization using the Four-Layer WebGL2 engine:

python -m phylo3d_trait.cli plot \
  --tree path/to/tree.nwk \
  --values path/to/node_values.csv \
  --output path/to/tree3d.html \
  --renderer four-layer \
  --opacity 0.85 \
  --reverse-colorscale \
  --curtain-color-mode branch \
  --centerline-color trait

Open tree3d.html directly in any modern web browser — no web server or internet connection required!


5. Command Line Interface (CLI) Reference

The CLI is invoked via python -m phylo3d_trait.cli <command> (or phylo3d-trait <command> when installed).

Subcommand: template-values

python -m phylo3d_trait.cli template-values -h
  • --tree, -t (required): Path to Newick or Nexus tree file.
  • --output, -o (required): Path to save the generated template CSV.
  • --default-val: Optional placeholder string for the trait column (default: "").

Subcommand: plot

python -m phylo3d_trait.cli plot -h

Core Inputs & Outputs

  • --tree, -t (required): Path to Newick or Nexus tree file.
  • --values, -v (required): Path to CSV or TSV trait values table.
  • --output, -o (required): Path to output standalone HTML file.
  • --title: Title displayed above the 3D scene.
  • --renderer {four-layer, plotly}: Rendering engine backend (default: plotly; four-layer recommended).

Rendering, Transparency & Aesthetics

  • --opacity: Curtain mesh opacity (default: 1.0). In four-layer mode, supports 0.5–1.0 (0%–50% transparency); in plotly mode, supports 0.0–1.0.
  • --curtain-color-mode {branch, height}: branch vertically projects local branch trait color; height applies a vertical gradient.
  • --centerline-color: Branch top outline color (dark [default], trait, or custom CSS color).
  • --colorscale: Continuous palette name (e.g. Turbo, Viridis, Plasma, Spectral, default: Turbo).
  • --reverse-colorscale: Reverses color palette without altering trait heights or raw values.
  • --branch-width: Line width for 3D branch top outlines (default: 1.0).
  • --background {white, transparent}: Background styling (default: white).
  • --segments, -s: Linear interpolation subdivisions per branch (default: 10).

Trait Geometry & Aspect Ratios

  • --baseline-y: Custom baseline $Y$ trait plane elevation (default: minimum observed trait).
  • --baseline-raw-value: Custom numeric trait value displayed at baseline $Y$ on axis and colorbar.
  • --trait-display-offset OFFSET: Geometric zero shift ($Y_{\text{display}} = \text{Trait}_{\text{raw}} - \text{OFFSET}$). Axis ticks and hover tooltips still show raw scientific values.
  • --trait-display-range START END: Linear remapping of raw traits [min, max] to target display coordinates [START, END].
  • --trait-axis-scale SCALE: Visual-only Trait ($Y$) axis aspect ratio multiplier (default: 1.0). E.g., 0.5 compresses visual height by half; 1.5 stretches it by 150%. Scientific values, ticks, colors, and mesh coordinates remain uncorrupted.

Camera, Labels & Viewport

  • --camera-preset {elife, root_front, tips_front}: Initial camera angle (default: elife).
  • --tip-label-offset FRACTION: Outward offset of terminal species labels beyond the present plane, expressed as a fraction of time span (default: 0.03).
  • --no-labels: Disable terminal taxon labels along the Tree Layout axis.

Display Toggles (Visual-Only Layer)

  • --no-x-axis: Hide Tree Layout ($X$) axis line and baseline markers.
  • --no-y-axis: Hide Trait value ($Y$) numerical axis line, ticks, labels, and title.
  • --no-z-axis: Hide Time before present ($Z$) numerical axis line, ticks, labels, and title.
  • --no-tip-hover: Disable interactive hover tooltip and indicator on terminal tip taxa.
  • --no-internal-hover: Disable interactive hover tooltip and indicator on internal ancestral nodes.
  • --no-mesh: Disable continuous curtain mesh surfaces.
  • --no-centerline: Disable branch top centerline outlines.
  • --show-node-markers: Render diamond markers at ancestral nodes (default: False).

6. Python API Reference

Phylo3D-Trait can be integrated directly into Python pipelines and computational workflows:

from phylo3d_trait import (
    parse_tree,
    build_plot_data,
    build_figure,
    build_four_layer_html,
)
from phylo3d_trait.io import load_trait_values

# 1. Parse tree and load trait table
tree = parse_tree("path/to/tree.nwk")
traits = load_trait_values("path/to/node_values.csv")

# 2. Build 3D plot data model
plot_data = build_plot_data(
    tree_input=tree,
    trait_values=traits,
    num_segments=10,
    colorscale="Turbo",
    curtain_color_mode="branch",
    reverse_colorscale=True,
)

# 3A. Render with modern Four-Layer WebGL2 engine (OIT + Adaptive Axes)
html_content = build_four_layer_html(
    plot_data=plot_data,
    opacity=0.85,
    camera_preset="elife",
    centerline_color="trait",
)
with open("tree3d_four_layer.html", "w", encoding="utf-8") as f:
    f.write(html_content)

# 3B. Or render with classic Plotly engine
fig = build_figure(
    plot_data=plot_data,
    camera_preset="elife",
    background="white",
)
fig.write_html("tree3d_plotly.html", include_plotlyjs="cdn")

7. Built-in Examples

Example 1: Standard 4-Taxon Dated Phylogeny

Example 1 3D Phylogeny

Example 2: 6-Taxon Nested Phylogeny with Baseline $Y = 0$

  • Tree: examples/example2/tree.nwk (nested multi-level clades)
  • Trait table: examples/example2/node_values.csv
  • Command:
    python -m phylo3d_trait.cli plot \
      --tree examples/example2/tree.nwk \
      --values examples/example2/node_values.csv \
      --output examples/example2/tree3d.html \
      --baseline-y 0 \
      --renderer four-layer
    

Example 2 3D Phylogeny


8. Installation & Testing

Install the stable release from PyPI:

pip install phylo3d-trait
phylo3d-trait --help

For development from source:

git clone https://github.com/hk20013106/Phylo3D-Trait.git
cd Phylo3D-Trait
pip install -e ".[dev]"
pytest tests/ -v

9. Citation, Support & Contributing

If you use Phylo3D-Trait in research, cite the software using CITATION.cff. A DOI will be added after archival release.

Current software citation:

He, K. (2026). Phylo3D-Trait: Deep-Time Macroevolutionary 3D Trait Visualization, version 0.3.2. GitHub: https://github.com/hk20013106/Phylo3D-Trait

The motivating macroevolutionary application concerns hemoglobin buffering power ($\beta\text{Hb4}$) and respiratory adaptation across deep-time mammal and bird phylogenies.

Contributing

Bug reports, reproducible rendering problems, feature requests, documentation improvements, and pull requests are welcome. Please use the GitHub issue templates and include the smallest reproducible tree/value files when reporting a visualization or parsing bug. See CONTRIBUTING.md before submitting code.

Project scope

Phylo3D-Trait is a visualization engine. It does not perform phylogenetic inference, tree dating, sequence analysis, statistical model fitting, or ancestral-state reconstruction.

Metadata

Release files for phylo3d-trait 0.3.2

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for phylo3d-trait 0.3.2
File Size Uploaded
phylo3d_trait-0.3.2.tar.gz 70.8 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for phylo3d-trait 0.3.2
File Interpreter ABI Platform
phylo3d_trait-0.3.2-py3-none-any.whl Python 3 none any Details

Total release size: 114.9 kB

Release files / phylo3d_trait-0.3.2.tar.gz

Download URL phylo3d_trait-0.3.2.tar.gz
Size 70.8 kB
Tags Source
SHA-256 checksum
How to use checksums
d46b1127aa822fa7120d61505348196b3c81802fdcca01e71ddb7107b06c31da
BLAKE2b-256 checksum
How to use checksums
e1a648b214c38d5ff3be8cd019478fc21cb53472804917b78e5220c150628e09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release files / phylo3d_trait-0.3.2-py3-none-any.whl

Download URL phylo3d_trait-0.3.2-py3-none-any.whl
Size 44.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
41cd337d67b25f2af3a6ff568ab162dbd3748a5b79b5fba3c4ed427cc9fa70ff
BLAKE2b-256 checksum
How to use checksums
447d8be6ae7d3636f58a8f9758d512d5fae9b12aa5c849699f91bdef0a2f8d00
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

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.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 29, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.2 This release

2 release files

0.3.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page