Interactive 3D cube visualization for multi-dimensional datasets
Project description
metacube (Python)
Interactive 3D cube visualization for tabular data. Provide a CSV and a config YAML — metacube transforms it and produces a self-contained HTML file or serves it locally.
Try it in the browser without installing →
Installation
pip install metacube
Quick Start
# Copy bundled example files
metacube examples --dest my_data/
# Explore interactively (no files written)
metacube dev my_data/census_tissue_general_counts.csv \
--config my_data/census_tissue_general.yaml
# Export a standalone HTML file
metacube export my_data/census_tissue_general_counts.csv \
--config my_data/census_tissue_general.yaml \
--output viz.html
CLI Reference
metacube dev — transform and serve in one step
metacube dev <CSV_FILE> --config <CONFIG_YAML> [--port 8000] [--no-browser]
Transforms the CSV in memory and serves a local visualization. Nothing is written to disk. Press Ctrl+C to stop.
metacube dev data.csv --config config.yaml
metacube dev data.csv --config config.yaml --port 9000 --no-browser
metacube export — transform and export in one step
metacube export <CSV_FILE> --config <CONFIG_YAML> [--output viz.html]
Produces a fully self-contained HTML file that works offline (no server needed). Default output name: <csv_stem>.html.
metacube export data.csv --config config.yaml
metacube export data.csv --config config.yaml --output my_viz.html
metacube transform — CSV → JSON
metacube transform <CSV_FILE> --config <CONFIG_YAML> [--output data.json]
Converts a CSV + config to an intermediate CubeData JSON. Use this when you want to cache the transformed data and serve or build from it later.
metacube transform data.csv --config config.yaml # writes data.json
metacube transform data.csv --config config.yaml -o out.json
metacube transform data.csv --config config.yaml | jq .config # pipe to jq
metacube build — JSON → HTML
metacube build <DATA_JSON> [--output cube.html]
Injects a pre-transformed CubeData JSON into the visualization template.
metacube build data.json
metacube build data.json --output my_viz.html
metacube serve — JSON → browser
metacube serve <DATA_JSON> [--port 8000] [--no-browser]
Serves a pre-transformed JSON locally.
metacube serve data.json
metacube serve data.json --port 9000
metacube examples — copy bundled example files
metacube examples [--dest ./] [--list]
Copies bundled example CSV and config YAML files to a local directory.
metacube examples # copy to current directory
metacube examples --dest my_data/ # copy to my_data/
metacube examples --list # print file names only
Python API
from metacube import csv_to_cube_data, build_html, serve
# Transform
data = csv_to_cube_data("data.csv", "config.yaml")
# Export standalone HTML
build_html(data, "viz.html")
# Serve locally
serve(data, port=8000, open_browser=True)
Step-by-step Workflow
# 1. Transform CSV → JSON (once, reuse for multiple outputs)
metacube transform dataset.csv --config config.yaml --output data.json
# 2a. Explore in browser
metacube serve data.json
# 2b. Or export for sharing
metacube build data.json --output shareable.html
Config YAML Reference
Full reference with all modes and examples: docs/config.md
The config YAML maps CSV columns to visualization axes and enables optional features.
Minimal config
title: "My Dataset"
axes:
x:
label: "Species"
column: "species"
y:
label: "Assay"
column: "assay"
z:
label: "Tissue"
column: "tissue"
size_colour: "cell_count"
Full config with all options
title: "My Dataset"
axes:
x:
label: "Organism"
column: "organism"
max_labels: 5 # keep only top N values by count (optional)
colors: # per-value hex colors (optional)
"Human": "#3b82f6"
"Mouse": "#10b981"
group_separator: " - " # group axis labels by prefix (optional)
y:
label: "Assay"
column: "assay"
max_labels: 20
z:
label: "Tissue"
column: "tissue"
max_labels: 30
size_colour: "cell_count" # numeric column for color gradient (omit for flat blue)
datasets_column: "dataset_id" # column of dataset IDs, shown in hover tooltip (optional)
# ── Drilldown: click a cell to see more detail ────────────────────────────────
drilldown:
# Option A: treemap popup (floating panel, stays alongside the cube)
type: "treemap"
category_column: "dataset_title" # outer grouping in the treemap
subcategory_column: "cell_type" # inner tiles in the treemap
count_column: "cell_count" # column to sum for tile size
# Option B: zoom into a finer-grained inner cube
# type: "zoom"
# axes:
# z: # redefine one or more axes
# label: "Organ"
# column: "organ"
# max_labels: 30
# size_colour: "cell_count"
# treemap: # optional: also show treemap panel in zoom view
# category_column: "dataset_title"
# subcategory_column: "cell_type"
# count_column: "cell_count"
# ── Slice: 2D matrix for the selected cell ───────────────────────────────────
slice:
fixed_axis: "x" # "x", "y", or "z" — the axis held fixed
count_column: "cell_count" # column to aggregate (optional)
# ── Info panel: structured text on click ─────────────────────────────────────
info:
columns:
title: "study_title"
author: "first_author"
year: "year"
doi: "doi"
url: "url"
# ── Axis ordering ─────────────────────────────────────────────────────────────
axis_order: "frequency" # "frequency" (default) or "cluster"
# frequency: labels ordered by descending total count
# (same rank as max_labels — most common first)
# cluster: after max_labels selection, labels are reordered
# by average-linkage cosine clustering on their
# co-occurrence profiles across the other two axes.
# Groups categories with similar occupancy patterns.
Config options summary
| Field | Required | Description |
|---|---|---|
title |
no | Visualization title shown in the header |
axes.{x,y,z}.column |
yes | CSV column name for each axis |
axes.{x,y,z}.label |
no | Display label (defaults to column name) |
axes.{x,y,z}.max_labels |
no | Keep only top N values by count |
axes.{x,y,z}.colors |
no | Map of value → hex color |
axes.{x,y,z}.group_separator |
no | String to split labels into groups |
size_colour |
no | Numeric column for colour gradient (omit for flat blue) |
datasets_column |
no | Column of dataset/study IDs, shown in hover tooltip |
drilldown |
no | Drilldown config (treemap or zoom) |
slice |
no | 2D matrix slice in the details panel |
info |
no | Structured entries shown as center modal on cell click |
info_box |
no | Structured entries shown inline in the side panel on cell click |
axis_order |
no | "frequency" (default) or "cluster" — see below |
axis_order: "frequency" (default): labels are presented in descending order of total count, matching the max_labels selection rank.
axis_order: "cluster": after max_labels selection, each axis is reordered by average-linkage hierarchical clustering on co-occurrence profiles. Each label becomes a row vector of its counts across all combinations of the other two axes (mode-k tensor unfolding); rows are L2-normalised and pairwise cosine distances feed scipy.cluster.hierarchy.linkage(method="average"). This groups categories with similar occupancy patterns together, making large-scale structure easier to read. This uses scipy, which is installed as a dependency of metacube. The R package uses stats::hclust and needs no additional dependencies.
Complete Example
Given a CSV data.csv:
organism,assay,tissue,study,cell_type,count
Human,scRNA-seq,blood,Study A,T cell,5000
Human,scRNA-seq,blood,Study A,B cell,2000
Human,scRNA-seq,liver,Study B,hepatocyte,8000
Mouse,scRNA-seq,blood,Study C,T cell,3000
And config.yaml:
title: "Single-cell Atlas"
axes:
x:
label: "Organism"
column: "organism"
y:
label: "Assay"
column: "assay"
z:
label: "Tissue"
column: "tissue"
size_colour: "count"
drilldown:
type: "treemap"
category_column: "study"
subcategory_column: "cell_type"
count_column: "count"
slice:
fixed_axis: "x"
count_column: "count"
metacube export data.csv --config config.yaml --output atlas.html
# Open atlas.html in any browser — no server needed
License
MIT — see LICENSE.
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 metacube-0.1.0.tar.gz.
File metadata
- Download URL: metacube-0.1.0.tar.gz
- Upload date:
- Size: 1.5 MB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
f76d55710436c57897e2317383281b996faf3f8baa855de681a1b7885911cf11
|
|
| MD5 |
3d7d7fd71a317ca3ee6b4e5e0875c168
|
|
| BLAKE2b-256 |
c2c43fd5c6020e92b1fb15e7e3e3ede84dfae543b0dc909c877391ae5c72a408
|
File details
Details for the file metacube-0.1.0-py3-none-any.whl.
File metadata
- Download URL: metacube-0.1.0-py3-none-any.whl
- Upload date:
- Size: 1.5 MB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
29c5feaa35ffcfc18241f1397d4f0f219301d346163508769b8407baab3c3e21
|
|
| MD5 |
b386cb0de305452015aab9b8f7e785ba
|
|
| BLAKE2b-256 |
dc2f5dc61cccd6e88f56bde54bc42560f6f6cdb6633dac3e2a98ee9ab8d7e5c4
|