Skip to main content

Clean API for reading and writing the SBML Layout extension

Project description

SBMLLayout

A clean Python API for attaching, editing, and rendering the SBML Layout extension.

Installation

pip install SBMLLayout

Why?

Existing tools (SBMLDiagrams, SBMLNetwork) are primarily visualisation tools that happen to expose a layout API as a side-effect. When you need to attach or manipulate layout geometry programmatically — especially with alias (repeated) species nodes or full bezier curves — you quickly hit undocumented requirements of the underlying libsbml Layout package. SBMLLayout takes care of all of that bookkeeping for you and includes its own skia-based renderer with full bezier support.

Quick start

import tellurium as te
from SBMLLayout import Layout

r = te.loada('''
    J1: S1 -> S2; k1*S1
    k1 = 0.1; S1 = 10; S2 = 0
''')

layout = Layout(r.getSBML())
layout.addNode('S1', x=100, y=150, w=60, h=40)
layout.addNode('S2', x=300, y=150, w=60, h=40)
layout.addReaction('J1', center=(200, 170),
                   reactants=['S1'], products=['S2'])

layout.draw()                        # display inline in Jupyter / IDE
layout.draw(output='network.png')    # save PNG  (scale=2 for high-DPI)
layout.draw(output='network.pdf')    # save PDF
layout.draw(output='network.svg')    # save SVG

Alias nodes

Species that appear more than once in a diagram (alias nodes) are supported as a first-class concept. Call addNode multiple times with the same species id and alias=True for each extra copy. Copy indices are assigned in call order (first call = copy 0, second = copy 1, …). Use 'A:1' syntax in reaction lists to route arms to a specific copy.

layout.addNode('A',  x=60,  y=200, w=50, h=40)             # prime  (copy 0)
layout.addNode('A',  x=280, y=300, w=50, h=40, alias=True)  # alias  (copy 1)

layout.addReaction('J1', center=(184, 205),
                   reactants=['S1'], products=['S2', 'A'])      # 'A' = copy 0
layout.addReaction('J2', center=(185, 346),
                   reactants=['S2', 'A:1'], products=['S3'])    # 'A:1' = copy 1

Bezier curves

Pass a handles list to addReaction to specify cubic bezier control points for each arm. Each entry is a pair of tuples ((BP1x, BP1y), (BP2x, BP2y)) where BP1 is near the species node and BP2 is near the junction. Use None for a straight-line arm.

# Bi-uni reaction: S1 + S2 -> S3 with curved reactant arms
layout.addReaction('J1',
    reactants=['S1', 'S2'],
    products=['S3'],
    center=(250, 203),
    handles=[
        ((210, 102), (240, 195)),  # S1 arm: (BP1, BP2)
        ((210, 302), (240, 211)),  # S2 arm: (BP1, BP2)
        None,                       # S3 arm: straight line
    ])

Direct reactions

For uni-uni reactions with no junction node, use direct=True. The line connects the reactant directly to the product with no junction circle.

# Straight direct line
layout.addReaction('J1', reactants=['S1'], products=['S2'], direct=True)

# Bezier direct curve
layout.addReaction('J1', reactants=['S1'], products=['S2'],
    direct=True,
    handles=[((160, 100), (240, 200))])  # single (BP1, BP2) pair

Compartments

layout.addCompartment('cell', x=10, y=10, w=500, h=400)

Method chaining

All add* methods return self, so calls can be chained:

layout = (Layout(r.getSBML())
    .addNode('S1', x=100, y=150, w=60, h=40)
    .addNode('S2', x=300, y=150, w=60, h=40)
    .addReaction('J1', center=(200, 170),
                 reactants=['S1'], products=['S2']))
layout.draw()

Using the SBML with other tools

toSBML() returns a valid SBML Level 3 string that can be loaded into any tool supporting the SBML Layout package:

sbml = layout.toSBML()

# SBMLDiagrams
import SBMLDiagrams
df = SBMLDiagrams.load(sbml)
df.draw()

# Or save for use elsewhere
with open('model_with_layout.xml', 'w') as f:
    f.write(sbml)

Styling

Pass a Style instance to draw() to customise the appearance. All colours are (R, G, B, A) tuples with values 0–255.

from SBMLLayout import Layout, Style

s = Style()
s.node_fill       = (200, 230, 255, 255)   # light blue fill
s.node_stroke     = (0,   80,  160, 255)   # dark blue border
s.reaction_stroke = (50,  50,  50,  255)   # dark grey lines
s.node_gap        = 10.0                   # gap between node edge and line
s.junction_visible = False                 # hide junction circles

layout.draw(output='network.png', scale=2, style=s)

Full Style reference

Attribute Default Description
Canvas
background_color (255,255,255,255) Canvas background colour
margin 30.0 Padding around the network in pixels
Compartments
compartment_fill (240,240,255,180) Compartment fill colour
compartment_stroke (100,100,200,255) Compartment border colour
compartment_stroke_width 2.0 Compartment border width
compartment_corner_radius 8.0 Compartment rounded corner radius
Species nodes
node_fill (250,213,211,255) Node fill colour
node_stroke (130,37,31,255) Node border colour
node_stroke_width 2.0 Node border width
node_corner_radius 6.0 Node rounded corner radius
Labels
label_color (0,0,0,255) Text colour
label_font_size 14.0 Font size in points
label_font_family 'Arial' Font family name
Reaction lines
reaction_stroke (0,0,0,255) Reaction line colour
reaction_stroke_width 2.0 Reaction line width
node_gap 6.0 Gap between node edge and start/end of reaction arms. Set to 0.0 for lines that touch the node edge exactly. Applies uniformly to reactant and product ends on all reaction styles.
Junction circle
junction_fill (130,37,31,255) Junction circle fill colour
junction_radius 5.0 Junction circle radius
junction_visible True Whether to draw the junction circle
Arrowhead
arrow_fill (0,0,0,255) Arrowhead fill colour
arrow_length 12.0 Arrowhead length (tip to base) in pixels
arrow_width 7.0 Arrowhead width at base in pixels

API reference

Layout(sbml_string)

Create a new layout for the given SBML Level 3 model string. Raises ValueError if the SBML is invalid or contains no model.

addNode(species_id, x, y, w=60, h=30, alias=False)

Add a species node. x, y are the top-left corner of the bounding box.

addReaction(reaction_id, reactants, products, center=None, handles=None, direct=False)

Add a reaction.

Parameter Description
reactants / products Lists of species refs. 'S1' = copy 0; 'A:1' = copy 1 of A.
center (x, y) junction point. Omit to let the renderer compute a default.
handles One ((BP1x,BP1y),(BP2x,BP2y)) pair per arm (reactants first, then products), or None for a straight arm. Omit entirely for all-straight lines.
direct If True, draw a single line/curve from reactant to product with no junction. For a direct bezier supply one handle pair.

addCompartment(compartment_id, x, y, w, h)

Add a compartment bounding box.

draw(output=None, scale=1.0, style=None)

Render the network. If output is omitted, displays inline (Jupyter / opens in default image viewer). Supported extensions: .png, .pdf, .svg.

toSBML()

Return a valid SBML Level 3 string with the Layout package embedded.

Compatibility

The SBML produced by toSBML() is compatible with:

Note on bezier curves and SBMLDiagrams

SBMLDiagrams does not read bezier curve data from the SBML Layout extension — it computes its own handle positions after loading. If you need bezier curves with SBMLDiagrams, use its setReactionBezierHandles API after SBMLDiagrams.load(). The SBMLLayout renderer reads and draws the full two-control-point cubic bezier data correctly.

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

sbmllayout-0.4.0.tar.gz (21.9 kB view details)

Uploaded Source

Built Distribution

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

sbmllayout-0.4.0-py3-none-any.whl (19.8 kB view details)

Uploaded Python 3

File details

Details for the file sbmllayout-0.4.0.tar.gz.

File metadata

  • Download URL: sbmllayout-0.4.0.tar.gz
  • Upload date:
  • Size: 21.9 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for sbmllayout-0.4.0.tar.gz
Algorithm Hash digest
SHA256 312b6fd9860959145b57235d58cd376270610cded8e928d3035609a727196548
MD5 75ba90574c6a3bf5d4f854adc508172a
BLAKE2b-256 a455ebb0b49a5bdd907e260ca3801bb65fec6068518e167dae8a1f0bd17d3118

See more details on using hashes here.

File details

Details for the file sbmllayout-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: sbmllayout-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 19.8 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.10

File hashes

Hashes for sbmllayout-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 34cadd9fb7fc956964cd0ba0aca5feb848e2f8ac18bf4e01a4f5a0c8674f67eb
MD5 ccb6b04b1cf1408b082546d3021c7847
BLAKE2b-256 d93e5861228db772929c514cc9be8dbec4bf1b42b552dc3bfb8ec6cd83530c5f

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