TMAP2
Tree-based visualization for high-dimensional data. Organizes similar items into interactive tree structures. Ideal for chemical space, protein embeddings, single-cell data, or any high-dimensional dataset.
Why Trees?
Most dimensionality reduction tools (UMAP, t-SNE, PCA) produce point clouds. TMAP produces a tree, a connected structure where every point is linked to its neighbors through branches. This makes the layout itself explorable because you can follow branches, trace paths between any two points, and discover how regions connect.
For example, in a TMAP of pet breed images, following the branch from terriers toward cats reveals that the bridge between the two groups runs through chihuahuas and sphynx cats (the bald ones) which is both hilarious and logical since both are small, have short hair, big eyes... The tree doesn't just cluster similar things it also shows you how dissimilar things are connected.
Because the layout is a tree, you get operations that point clouds can't support:
path = model.path(idx_a, idx_b) # nodes along the tree path
d = model.distance(idx_a, idx_b) # sum of edge weights along the path
n = model.hops(idx_a, idx_b) # number of tree edges between two points
pseudotime = model.distances_from(idx) # tree distance from one point to all others
The same path tracing and tree-distance colouring are available inside the interactive HTML: pin two points and the inspector lists the path, or colour the whole map by tree distance from a selected point.
Installation
pip install tmap2
Wheels are published for Linux x86_64, macOS arm64 (Apple Silicon), and Windows x86_64 on Python 3.11 to 3.13. Other platforms build the OGDF layout extension from source and need CMake and a C++17 compiler.
Optional extras:
pip install rdkit # chemistry helpers (fingerprints_from_smiles, molecular_properties)
pip install jupyter-scatter # notebook interactive widgets
pip install biopython # protein helpers (ProtParam properties, PDB parsing)
Note: The import name is
tmap, nottmap2.
Quick Start
Binary Data (e.g. Chemical Fingerprints)
from tmap.utils import fingerprints_from_smiles
from tmap import TMAP
smiles = [...] # your SMILES list
# Binary fingerprints (Jaccard distance). `valid` flags the SMILES RDKit could parse,
# so you can drop the same rows from any labels or properties you attach later.
fps, valid = fingerprints_from_smiles(smiles, fp_type="morgan", radius=2, n_bits=2048, return_valid=True)
model = TMAP(metric="jaccard", n_neighbors=20).fit(fps)
viz = model.to_tmapviz()
viz.write_html("map.html") # interactive HTML, open in a browser
# viz.show() # or render inline in a Jupyter notebook
Continuous Vectors (e.g. Protein Embeddings)
import numpy as np
from tmap import TMAP
# embeddings (use cosine / euclidean distances)
X = np.random.random((1000, 128)).astype(np.float32)
model = TMAP(metric="cosine", n_neighbors=20).fit(X)
viz = model.to_tmapviz()
viz.show() # inline in a Jupyter notebook
# viz.write_html("tmap.html") # or save as interactive HTML
Key Features
- Tree structure: follow branches, trace paths, count hops, compute pseudotime
- Always one tree: a too-low
n_neighborscan fragment the kNN graph; TMAP bridges the pieces sopathanddistancestay defined (connect_components=True, inspect withn_components_) - Deterministic: the layout is always seeded and deterministic. For cosine/euclidean, pass
reproducible=Trueto also make the HNSW index build bit-identical across runs (slower) - Multiple metrics:
jaccard,cosine,euclidean,precomputed, or bring your own kNN graph - Incremental:
add_points()andtransform()for adding new data into an existing TMAP - Model persistence:
save()/load() - Three viz backends: interactive HTML, jupyter-scatter, matplotlib
Visualization (add colors, labels...)
Notebook widgets: color switching, categorical filtering, and lasso selection with pandas-backed metadata:
Add Colors & Labels
Adding colors is quite simple. Just pass the name of the layout (e.g. Molecular Weight, Age, Protein Lenght ...), a list of values for each node and matplotlib color.
If the data is categorical (e.g. Age or Heavy Atom Count) pass categorical=True so that categorical colors like tab10 become available.
To add labels (i.e. data that is not needed for coloring the nodes) just pass a name for the labels and the list of values.
model = TMAP(metric="jaccard").fit(X)
viz = model.to_tmapviz()
viz.add_color_layout("Molecular Weight", mw.tolist(), categorical=False)
viz.add_color_layout("Scaffold", scaffolds, categorical=True, color="tab10")
viz.add_label("SMILES", smiles_list)
viz.show(width=1000, height=620, controls=True) # to see in jupyter notebook
# viz.write_html("mytmap.html") # to save and see as HTML in the browser
Here SMILES are added as a plain label, so no 2D structure is drawn. To render structures in tooltips and cards, use
viz.add_smiles(smiles_list)instead. For image datasets useviz.add_images(paths_or_urls).
Filters, cards and structures
viz.add_filter("Ring Count", n_rings, categorical=True) # filter-panel column without a colour map
viz.configure_column("UniProt ID", link_template="https://www.uniprot.org/uniprotkb/{value}")
viz.configure_card(title_column="Name", fields=["Molecular Weight", "Scaffold"])
viz.add_3d_structures(alphafold_urls, source="url", fmt="pdb") # or add_3d_structure_files(local_paths)
add_filter puts a column in the filter panel without computing colours for it, which is cheaper than add_color_layout when you only want to filter. Colour layouts are always filterable. configure_column and configure_card control links, formatting and what the pinned card shows. add_3d_structures and add_3d_structure_files attach PDB or mmCIF structures that render in the card.
Interactive HTML
viz.write_html("name.html") writes a self-contained page with lasso selection, light/dark theme, filter and search panels, pinned metadata cards, and a binary mode for large datasets. Selecting a point opens the inspector:
- Neighbors: the point's tree neighbours with similarity scores, property differences and structures or images. Hovering a neighbour highlights the connecting edge.
- Path: pin a second point to trace the tree path between them, listing each node with its step number and running tree distance.
- Colour by tree distance: colour the whole map by tree distance from the selected point, using the normal colour menu.
For publication figures use matplotlib: model.plot_static(color_by=labels).
Domain Utilities
Built-in helpers for common scientific workflows:
from tmap.utils.chemistry import fingerprints_from_smiles, molecular_properties
from tmap.utils.proteins import fetch_uniprot, sequence_properties
from tmap.utils.singlecell import from_anndata
| Domain | Metric | Utilities |
|---|---|---|
| Chemoinformatics | jaccard |
fingerprints_from_smiles (return_valid=True flags unparseable SMILES), molecular_properties, murcko_scaffolds, reaction_properties |
| Proteins | cosine / euclidean |
fetch_uniprot, fetch_alphafold, read_fasta, read_pdb, read_pdb_dir, read_protein_csv, sequence_properties, parse_alignment |
| Single-cell | cosine / euclidean |
from_anndata, cell_metadata, marker_scores, obs_to_numeric, subset_anndata, sample_obs_indices |
| Generic embeddings | cosine / euclidean / precomputed |
No domain utils needed |
Examples
Runnable scripts for chemistry, images, proteins and text live in examples/. The shortest one is:
python examples/chemistry/molecules_tmap.py --nrows 3000
Notebooks
| Notebook | Topic |
|---|---|
| 01 Quickstart | Shortest end-to-end walkthrough on a small molecule table |
| 02 Cheminformatics | SMILES → fingerprints → interactive molecular map |
| 03 Continuous Embeddings | Cosine and euclidean on MNIST: when to use each |
| 04 What's New | add_points, transform, tree paths, save/load, external kNN |
| 05 Single-Cell | RNA-seq with PBMC 3k, pseudotime, UMAP comparison |
| 06 FAQ | Troubleshooting and common questions |
| 07 MinHash Deep Dive | Encoding methods and when to use each |
| 08 Notebook Widgets | Coloring, tooltips, lasso selection with jupyter-scatter |
| 09 Card Configuration | Pinned card layout, fields, and links |
| 10 Protein Analysis | FASTA, ESM embeddings, AlphaFold |
| 11 USearch Jaccard | Native binary Jaccard backend (high recall, low memory) |
| 12 Legacy LSH Pipeline | Lower-level MinHash + LSHForest + layout workflow |
| 13 Local Protein Structures | Pinned cards with locally stored PDB/mmCIF structures |
| 14 CAZyme Analysis | GH43 glycoside hydrolase family map, contributed example |
Lower-Level Pipeline
For direct control over indexing, hashing, and layout, see the legacy pipeline notebook. The main building blocks:
from tmap.index import USearchIndex # dense / binary kNN
from tmap import MinHash, LSHForest # Jaccard on sets / strings
from tmap.layout import LayoutConfig, layout_from_lsh_forest
Your Data
├─→ Binary matrix ─────────→ USearch (Jaccard / cosine / euclidean)
└─→ Sets / strings ───────→ MinHash → LSHForest
↓
k-NN Graph → MST → OGDF Tree Layout → Interactive Visualization
Development
git clone https://github.com/afloresep/tmap2.git
cd tmap2
pip install ".[dev]"
pytest -v
License
MIT License; see LICENSE for details.
Citation
If you use TMAP2 in your research, please cite:
From Proteins and Molecules to Cats and Dogs: Visualization as Scalable Minimum Spanning Trees
Alejandro Flores Sepúlveda, Maarten Boneschansker, Daniel Probst, Jean-Louis Reymond
ChemRxiv, 2026.
https://doi.org/10.26434/chemrxiv.15008307/v1
@article{floressepulveda2026tmap,
title = {From Proteins and Molecules to Cats and Dogs: Visualization as Scalable Minimum Spanning Trees},
author = {Flores Sepúlveda, Alejandro and Boneschansker, Maarten and Probst, Daniel and Reymond, Jean-Louis},
year = {2026},
doi = {10.26434/chemrxiv.15008307/v1},
url = {https://doi.org/10.26434/chemrxiv.15008307/v1},
note = {ChemRxiv preprint}
}
Metadata
Release files for tmap2 0.3.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| tmap2-0.3.1.tar.gz | 4.5 MB | Details |
Built distributions (wheels)
| File | Reset | |||
|---|---|---|---|---|
| tmap2-0.3.1-cp313-cp313-win_amd64.whl | CPython 3.13 | CPython 3.13 | Windows x86-64 | Details |
| tmap2-0.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.13 | CPython 3.13 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| tmap2-0.3.1-cp313-cp313-macosx_11_0_arm64.whl | CPython 3.13 | CPython 3.13 | macOS 11.0+ ARM64 | Details |
| tmap2-0.3.1-cp312-cp312-win_amd64.whl | CPython 3.12 | CPython 3.12 | Windows x86-64 | Details |
| tmap2-0.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.12 | CPython 3.12 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| tmap2-0.3.1-cp312-cp312-macosx_11_0_arm64.whl | CPython 3.12 | CPython 3.12 | macOS 11.0+ ARM64 | Details |
| tmap2-0.3.1-cp311-cp311-win_amd64.whl | CPython 3.11 | CPython 3.11 | Windows x86-64 | Details |
| tmap2-0.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl | CPython 3.11 | CPython 3.11 | Linux glibc 2.27+ x86-64, Linux glibc 2.28+ x86-64 | Details |
| tmap2-0.3.1-cp311-cp311-macosx_11_0_arm64.whl | CPython 3.11 | CPython 3.11 | macOS 11.0+ ARM64 | Details |
Total release size: 13.7 MB
Release files / tmap2-0.3.1.tar.gz
| Download URL | tmap2-0.3.1.tar.gz |
|---|---|
| Size | 4.5 MB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
19d4073478828c0d3bf809d91ac759f21e3d2eb986527f8246ebd5658fb00895
|
|
BLAKE2b-256 checksum How to use checksums |
9215f154743edf4c3d27ac6b0c96c203e91fa8931b0483609ba307a22d72f9e8
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp313-cp313-win_amd64.whl
| Download URL | tmap2-0.3.1-cp313-cp313-win_amd64.whl |
|---|---|
| Size | 779.6 kB |
| Tags | CPython 3.13 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
8fdcc779af6ca117b3f00b2c22ed9e98989c40d15a6cabe717718335a2cf385f
|
|
BLAKE2b-256 checksum How to use checksums |
fd53221e9f0207dc90849ccd14b3cbfcae9aa69c55549e0aaf49699829804866
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | tmap2-0.3.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.13 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
24027e5864485f35ed317c1858eeff0acf57e57aa00ca3d7dd746c0f5893158f
|
|
BLAKE2b-256 checksum How to use checksums |
0b7e0a9a8836788d015aa20dcb07502cb548836b13e2d662511eccaaad367987
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp313-cp313-macosx_11_0_arm64.whl
| Download URL | tmap2-0.3.1-cp313-cp313-macosx_11_0_arm64.whl |
|---|---|
| Size | 962.7 kB |
| Tags | CPython 3.13 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
08e1905aa934f6a1f066bea16adab8d82ba029ce1237d249c96a4aa11d1ec69b
|
|
BLAKE2b-256 checksum How to use checksums |
1be36f305d51ce8dfa12a8f5d7c9709ddeaf914d046de3d20b88b919a22cebc2
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp312-cp312-win_amd64.whl
| Download URL | tmap2-0.3.1-cp312-cp312-win_amd64.whl |
|---|---|
| Size | 779.6 kB |
| Tags | CPython 3.12 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
de4b9ac84230a07f8260237d5ddef4853d25a09f14790dc28f72798c84ebf9c2
|
|
BLAKE2b-256 checksum How to use checksums |
d38fc7c4b13eab5399769f2c2c1ea652e40abe888b885384d4c374f2c24f0022
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | tmap2-0.3.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.12 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
63605a67d6161c34a6c7a02f154f92af6b9a01b83e546cad0415d299586ddd66
|
|
BLAKE2b-256 checksum How to use checksums |
447f7b8f77ca3a735390af3be386b3e6a04f7815f0895a2b6f6ebb3e5a74d15e
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp312-cp312-macosx_11_0_arm64.whl
| Download URL | tmap2-0.3.1-cp312-cp312-macosx_11_0_arm64.whl |
|---|---|
| Size | 962.6 kB |
| Tags | CPython 3.12 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
1cdd2af0546c34d06d4972b96adbb5a3d030a5b68066378b3a3d79541198f763
|
|
BLAKE2b-256 checksum How to use checksums |
5baacd9d859e525cf2acdea11eb2de60e33a505fece4a45a6585d540e41d76e0
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp311-cp311-win_amd64.whl
| Download URL | tmap2-0.3.1-cp311-cp311-win_amd64.whl |
|---|---|
| Size | 777.1 kB |
| Tags | CPython 3.11 Windows x86-64 |
|
SHA-256 checksum How to use checksums |
083a206f047d302daaf268a78bb6bc29954e7338cb6c18de8bb082cc4d11de88
|
|
BLAKE2b-256 checksum How to use checksums |
e6d5304023d0a62e37bab9739131717c05619cd34751f6fd5cecb7f188bae813
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl
| Download URL | tmap2-0.3.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl |
|---|---|
| Size | 1.3 MB |
| Tags | CPython 3.11 Linux glibc 2.27+ x86-64 Linux glibc 2.28+ x86-64 |
|
SHA-256 checksum How to use checksums |
120d93ed143e429668e4fdbf4c36ecdf6056be45267317a8f55b6af40577800c
|
|
BLAKE2b-256 checksum How to use checksums |
f5a532fb31345edf2a590b866b4c2894ed953ba8f2dd4c8cd0a1aab04fea5eb9
|
| 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 14, 2026.
Transparency logRelease files / tmap2-0.3.1-cp311-cp311-macosx_11_0_arm64.whl
| Download URL | tmap2-0.3.1-cp311-cp311-macosx_11_0_arm64.whl |
|---|---|
| Size | 961.8 kB |
| Tags | CPython 3.11 macOS 11.0+ ARM64 |
|
SHA-256 checksum How to use checksums |
4254f31dc507c6e97656b8ce71c19e90a0330f03e0f4f990f215b1a933ce6cf7
|
|
BLAKE2b-256 checksum How to use checksums |
f25a0d6ae64c3a9c7d4f23097ae2b27efcffd8ac35498138ac5607693b721578
|
| 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 14, 2026.
Transparency log