Subway-style pipeline diagrams for matplotlib
Project description
Subway-style pipeline diagrams for matplotlib. Define stations on a grid and lines that connect them; the renderer handles right-angle routing, parallel-track offsets where lines share segments, and station labels.
Install
pip install metroplot
Or from source:
git clone https://github.com/s-weissbach/metroplot.git
cd metroplot
pip install -e .
Only hard dependency is matplotlib.
Usage
import matplotlib.pyplot as plt
from metroplot import Diagram
NAVY, SALMON = "#1f2a44", "#e07a6b"
d = Diagram()
(d.station("sra", 0.0, 0.0, "SRA tool", "DATA DOWNLOAD", "below")
.station("fastqc", 2.0, 0.0, "fastqc", "QUALITY CONTROL")
.station("star", 6.0, 0.0, "STAR", "ALIGNMENT")
.station("rmats", 9.0, 0.0, "rMATS", "ALT SPLICING")
.station("bam", 8.0, -1.5, "bamCoverage", "COVERAGE", "below")
.station("fc", 6.0, -2.5, "featureCounts", "QUANTIFICATION", "below"))
# A line is a list of routes. Multiple routes that share a station encode a split.
d.line("splicing", SALMON, [
["sra", "fastqc", "star", "rmats"],
["rmats", "bam"], # branch off rmats
])
d.line("quant", NAVY, [
["sra", "fastqc", "star", "fc"],
])
d.render()
plt.savefig("pipeline.png", dpi=150, bbox_inches="tight")
Run examples/example.py to regenerate the figure at the top.
CLI
After pip install metroplot the metroplot command is available:
# From a Snakemake workflow directory
metroplot snakemake path/to/workflow -o pipeline.png
# From a Nextflow DSL2 directory
metroplot nextflow path/to/workflow -o pipeline.png
# Common options
metroplot snakemake path/to/workflow \
--line-name "My pipeline" \
--color "#1f2a44" \
--label-overrides '{"star_align":"STAR"}' \
--sub-overrides '{"star_align":"ALIGNMENT"}' \
--column-spacing 2.5 \
--branch-spacing 2.5 \
--no-legend \
--dpi 300 \
--figsize 18 6
Pipeline workflows
metroplot ships with parsers that turn a workflow definition into a Diagram automatically. Two formats are supported:
- Snakemake —
from metroplot.snakemake_io import from_snakemakeparses everySnakefile/*.smkunder a directory, matches each rule'soutput:paths to downstreaminput:paths to derive the DAG. - Nextflow (DSL2) —
from metroplot.nextflow_io import from_nextflowparses every*.nffile, findsprocess NAME { … }blocks, and extracts edges by readingworkflow { … }blocks for invocations likeSTAR(TRIM.out).
Both share the same downstream layout/Diagram-builder (metroplot._pipeline_layout): the longest source-to-sink path becomes the y = 0 spine, off-spine rules drop below at branch_spacing, and every parameter (label overrides, sub-labels, lanes, colors, column spacing) is exposed as a kwarg.
from metroplot.snakemake_io import from_snakemake # or: from metroplot.nextflow_io import from_nextflow
d = from_snakemake(
"path/to/workflow",
line_name="My pipeline",
label_overrides={"run_method": "scanpy/Seurat"}, # snake_case rule name → display label
sub_overrides={"run_method": "ANNOTATION"}, # small uppercase line under each label
lanes={ # optional: split into multiple parallel lines
"QC": {"color": "#aaaaaa", "rules": ["FASTQC", "MULTIQC"]},
"Main": {"color": "#1f2a44", "rules": ["FASTP", "STAR", "FEATURECOUNTS", "DESEQ2"]},
},
)
d.render()
End-to-end demos:
- Snakemake on a real cell-type annotation benchmarking workflow → examples/example_snakemake.py → graphics/snakemake_example.png
- Nextflow on an nf-core-style RNA-seq pipeline → examples/example_nextflow.py → graphics/nextflow_example.png
Both parsers are best-effort regex-based and do not understand dynamic rules / checkpoint outputs (Snakemake) or subworkflow imports / channel operators like map, branch, combine (Nextflow). For anything they miss, override at the kwarg layer or pass extra rules/edges into metroplot._pipeline_layout.build_diagram_from_dag directly.
Concepts
- Station — a node at
(x, y)on a grid. You control layout fully; there's no auto-layout. - Line — a colored route, owning one or more
routes(lists of station names). Splits are implicit: two routes that share a station diverge there. - Shared segments — when multiple lines traverse the same
(a, b)segment, they're auto-offset perpendicular to the segment so they render as parallel tracks. - Bends — non-collinear hops use an L-shape. Per-line
bend="hv"(horizontal then vertical, default) or"vh".
Tuning
Diagram(track_spacing=..., station_radius=..., line_width=..., label_font=..., sub_font=...) exposes the visual knobs.
Testing
pip install -e ".[dev]"
pytest
CI runs the suite on Python 3.10, 3.11, and 3.12 (see .github/workflows/test.yml).
License
MIT.
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 metroplot-0.1.0.tar.gz.
File metadata
- Download URL: metroplot-0.1.0.tar.gz
- Upload date:
- Size: 19.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6db02b8712be1bc89d3962a95dd87d525601e48bae9f7af2f440d8d88d2a189a
|
|
| MD5 |
c21ce8c4d166d46b6928d7060f0feb30
|
|
| BLAKE2b-256 |
e55b076fe836b8c9c51815d485b70b22be85827281e4df54b28ace501732878d
|
File details
Details for the file metroplot-0.1.0-py3-none-any.whl.
File metadata
- Download URL: metroplot-0.1.0-py3-none-any.whl
- Upload date:
- Size: 16.0 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.11.15
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4df643af21323308db805fdecefcae771b1283ff28a5ee21eab47b46dfc248af
|
|
| MD5 |
e516dedb74061f4f318281e583bea06f
|
|
| BLAKE2b-256 |
9d8d071aed440d52cf26fc517693891c8ecc5f7a41bc67077f267051a0153618
|