Skip to main content

Metabolic neighborhood visualization for COBRApy genome-scale models

Project description

PyPyrus Map

Metabolic neighborhood visualization for COBRApy genome-scale models.

PyPyrus Map lets you instantly visualize the full reaction neighborhood of any metabolite in a COBRApy-compatible genome-scale model, including heterologous and non-native pathways that curated databases like Escher cannot represent. Output is publication-quality vector figures (SVG, PDF) suitable for direct journal submission.


Why PyPyrus Map exists

PyPyrus Map was built out of a concrete research problem during Project Menhed, an in silico metabolic engineering effort to optimize lycopene production across multiple chassis organisms. When working with heterologous carotenoid biosynthesis pathways, standard tools like Escher were limited to pre-drawn maps, they could not show the neighborhood of a non-native intermediate like GGPP or Phytoene, making it difficult to quickly identify overexpression and knockout targets.

The need was simple: given a metabolite of interest, show every reaction that produces or consumes it, who the other substrates and products are, and when an FBA solution is available, what the flux through each reaction looks like. PyPyrus Map was written to answer that question in one function call.


Installation

Recommended (includes Graphviz for publication-quality layout):

pip install "pypyrus-map[graphviz]"

Minimal:

pip install pypyrus-map

System dependency for Graphviz layout (required for layout="dot"):**

# Ubuntu / Debian / Google Colab
apt-get install graphviz graphviz-dev
pip install pygraphviz

# macOS
brew install graphviz
pip install pygraphviz

Install directly from GitHub:

pip install git+https://github.com/NoureldenRihan/PyPyrus-Map.git

Quick start

import cobra
from pypyrus_map import PyPyrusMap

# Load any COBRApy-compatible genome-scale model
model = cobra.io.load_json_model("iML1515.json")
solution = model.optimize()

# Create a session and explore a metabolite neighborhood
session = PyPyrusMap(model, solution=solution)
session.add("ggpp_c")

fig = session.render(title="GGPP Neighborhood")
fig.show()

# Export publication-quality vector figures
session.export("ggpp_neighborhood.svg")
session.export("ggpp_neighborhood.pdf")

Chaining metabolites

PyPyrus Map is designed for pathway chains. Call .add() multiple times to build up a connected pathway graph, shared nodes are never duplicated.

session = PyPyrusMap(model, solution=solution)

# Build a carotenoid biosynthesis chain
session.add("ipdp_c")    # IPP neighborhood
session.add("frdp_c")   # FPP neighborhood neighborhood
# session.add("lycopene_c")  # works for heterologous and non native introduced metabolites too!

fig = session.render(
    title="Isoprenoid Pathway: IPP → FPP",
    orientation="portrait",
    label_mode="id",
)
session.export("isoprenoid_chain.svg")

When you call session.add("frdp_c"), PyPyrus Map queries FPP's full depth-1 neighborhood and merges it into the existing graph. The IPP node is already present, it gets promoted to anchor status rather than duplicated. Any other producers of Phytoene also appear automatically, because this is the full neighborhood, not just a single edge.


Visualization options

fig = session.render(
    layout="dot",              # 'dot' (default) | 'spring' | 'circular'
    orientation="landscape",   # 'landscape' (default) | 'portrait'
    figsize=None,              # auto-sized from node count; override with (width, height)
    title=None,                # auto-generated from anchor IDs if None
    label_mode="id",           # 'id' (default) | 'truncate' | 'full'
    show_flux_labels=False,    # show flux values (4 dp) on edge midpoints
    show_stoichiometry=False,  # show stoichiometric coefficients on edges
    dpi=110,                   # screen resolution; SVG/PDF always lossless
    font_family="DejaVu Sans", # 'Arial' matches Nature/Cell/Science guidelines
)

Label modes

Mode Shows Best for
"id" BiGG ID (e.g. ggpp_c) Default, compact, unambiguous
"truncate" Human name, max 20 chars Readable without overlap
"full" Full human name Presentations, wide figures

Visual encoding

Element Meaning
Deep blue square Focal metabolite (anchor)
Sky blue square Neighbor metabolite
Amber diamond Reaction
Amber diamond, thick black border Reaction with zero flux (blocked)
Teal-green arrow Produces (reaction → metabolite)
Magenta-pink arrow Consumes (metabolite → reaction)
Double-headed arrow Reversible reaction
Colored arrow with black outline Edge through a blocked reaction

Flux overlay

When a cobra.Solution is passed at session construction, flux values are attached to each reaction node. Blocked reactions (flux ≈ 0) are visually distinguished by a thick black border on the reaction diamond and a black outline on their connecting arrows, visible even on short connections.

solution = model.optimize()
session = PyPyrusMap(model, solution=solution)
session.add("ggpp_c")

# Show flux values on edges
fig = session.render(show_flux_labels=True)

Currency metabolite suppression

High-connectivity cofactors (ATP, NADH, H₂O, CoA, Pi, etc.) connect nearly every reaction in the model to every other. By default, PyPyrus Map suppresses these from neighbor nodes to keep figures clean. The focal metabolite is always shown regardless.

# Default: currency suppressed
session = PyPyrusMap(model)

# Show everything including currency metabolites
session = PyPyrusMap(model, suppress_currency=False)

# Custom currency list
my_currency = frozenset({"h_c", "h_e", "atp_c", "adp_c"})
session = PyPyrusMap(model, custom_currency_ids=my_currency)

The default currency ID list is available as pypyrus_map.DEFAULT_CURRENCY_IDS and follows the conventions of Huss & Holme (2007) and KEGG RPAIR.


Error handling

PyPyrusMap uses strict BiGG IDs, no fuzzy matching. If an ID is not found, a clear error is raised with prefix-matched candidate suggestions:

from pypyrus_map import MetaboliteNotFoundError

try:
    session.add("ggpp_m")   # wrong compartment
except MetaboliteNotFoundError as e:
    print(e)
# MetaboliteNotFoundError: 'ggpp_m' not found in model.
# Did you mean: ggpp_c?

Session API

PyPyrusMap(model, solution=None, suppress_currency=True, custom_currency_ids=None)

Parameter Type Default Description
model cobra.Model required Any COBRApy-compatible genome-scale model
solution cobra.Solution None FBA solution - enables flux overlay
suppress_currency bool True Suppress high-connectivity cofactors from neighbor nodes
custom_currency_ids frozenset[str] None Replace the default currency list entirely

Session methods

Method Returns Description
session.add(metabolite_id) self Add a metabolite neighborhood. Chainable.
session.remove(metabolite_id) self Remove a metabolite and its orphaned reactions. Chainable.
session.clear() self Reset the session graph entirely.
session.render(**kwargs) Figure Render and return a Matplotlib figure.
session.export(path, dpi=300) Path Save figure to SVG, PDF, PNG, or TIFF.
session.build() PathwayGraph Return the raw graph object for custom processing.
session.summary() str Print a text summary of current session state.

Development

git clone https://github.com/NoureldenRihan/PyPyrus-Map.git
cd PyPyrusMap
pip install -e ".[dev]"
pytest tests/ -v

Citing PyPyrusMap

If PyPyrusMap contributes to a published work, please cite:

Rihan, N. PyPyrus Map: Metabolic neighborhood visualization for COBRApy genome-scale models. GitHub, 2026. https://github.com/NoureldenRihan/PyPyrus-Map

A Zenodo DOI and formal citation file (CITATION.cff) will be added shortly.


Acknowledgements

PyPyrusMap was developed with the assistance of Claude (Anthropic), a large language model used for code generation and implementation. All research direction, architectural decisions, feature design, and validation were conceived and directed by the author.

PyPyrus Map was built as part of Project Menhed, an in silico metabolic engineering initiative targeting lycopene biosynthesis optimization.


License

MIT License — Copyright (c) 2026 Nourelden Rihan. See LICENSE for details.

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

pypyrus_map-0.1.0.tar.gz (28.7 kB view details)

Uploaded Source

Built Distribution

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

pypyrus_map-0.1.0-py3-none-any.whl (25.5 kB view details)

Uploaded Python 3

File details

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

File metadata

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

File hashes

Hashes for pypyrus_map-0.1.0.tar.gz
Algorithm Hash digest
SHA256 f4dc00691bd8a4beb5730d05dc0fb999997f75bd1e7a662faa0f1be00e6fb6c0
MD5 0ae25b5d2847c4263c8e7fb714bbc87a
BLAKE2b-256 260989276af6f412ae8cccee743749d73b0d5d360ecdc43f266a64eb8b6599a3

See more details on using hashes here.

File details

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

File metadata

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

File hashes

Hashes for pypyrus_map-0.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 0e1c649e5709d52975ede899396a26d8be9b626b94cd40acae97d295d44b6e31
MD5 13000951d81741a2c69adb235e688bd3
BLAKE2b-256 cae027eb7484efc3a1288d40dffe07424e956a92a39ae7a2a93d225e448e4f13

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