schematic

plot.schematic

Population-schematic diagrams for neural-mass / mean-field / spiking models.

Renders the excitatory/inhibitory population circuit of a model: population nodes plus typed, signed connections — synapse type (NMDA / AMPA / GABA / …) sets the line colour, biophysical sign sets the terminal (excitatory , inhibitory ) — within a population, between populations, as recurrent self-loops, and across n_areas coupled areas. It is the standing “what is this model” diagram every recipe wants (Deco 2014 Fig. 1a/2a, Jansen-Rit, …).

Rendering backend = graphviz layout + matplotlib draw. graphviz (the dot engine) solves node placement and edge-spline routing — its strength — and matplotlib draws the result with full styling control: crisp custom arrowheads, endpoints snapped to node edges, small compact self-loops, neuron-dot population glyphs, and publication typography. This beats either alone (graphviz styling is rigid; hand-placed matplotlib arrows don’t route cleanly).

Two entry points:

  • Declarative — build Population / Connection objects → PopulationSchematic.
  • Model-derivedPopulationSchematic.from_dynamics(dynamics) reads a tvbo Dynamics: populations are its state variables (S_EE); connections are recovered by expanding the derived variables into each state variable’s dfun and classifying every cross-population term by the sign of its coefficient and the synapse named in the multiplying parameter.

Flexible layout/style, all via plot(...) keywords:

  • layout: "stacked" (E-row over I-row, the DMF look) · "mirror" ([I E]…[E I], the paired-area spiking look) · "row" (single rank).
  • glyph: "circle" · "neurons" (dotted population = spiking) · a callable.
  • self_loop, coupling_blob, ellipsis, legend/legend_labels, synapse_colors, node_size, ranksep/nodesep — all tunable.

Attributes

Name Description
SYNAPSE_COLORS

Classes

Name Description
Connection Directed connection source → target.
Population One neural population (a node). sign = "excitatory" (open node) / "inhibitory" (filled). label is the glyph inside the node (defaults to name).
PopulationSchematic A renderable population circuit: populations + typed/signed connections over N areas.

Connection

plot.schematic.Connection(
    source,
    target,
    synapse=None,
    sign='excitatory',
    scope='local',
    label=None,
    recurrent=None,
)

Directed connection source → target.

synapse (NMDA/AMPA/GABA) sets colour; sign (excitatory ▶ / inhibitory ●) sets the terminal; scope is "local" (within an area) or "long_range" (between adjacent areas). recurrent (self-loop) is inferred from source == target when omitted.

Population

plot.schematic.Population(name, sign='excitatory', label=None)

One neural population (a node). sign = "excitatory" (open node) / "inhibitory" (filled). label is the glyph inside the node (defaults to name).

PopulationSchematic

plot.schematic.PopulationSchematic(populations, connections, n_areas=1)

A renderable population circuit: populations + typed/signed connections over N areas.

Methods

Name Description
from_dynamics Derive the schematic from a :class:Dynamics, reading populations off its state variables and connections off its equations.
plot Render the schematic onto ax (created if None). Returns the axis.
from_dynamics
plot.schematic.PopulationSchematic.from_dynamics(
    dynamics,
    n_areas=1,
    long_range_synapse='AMPA',
    synapse_map=None,
    coupling_symbols=('c_glob', 'coupling', 'gx', 'local_coupling'),
)

Derive the schematic from a :class:Dynamics, reading populations off its state variables and connections off its equations.

coupling_symbols names the symbols that mark a long-range input, which becomes a connection carrying long_range_synapse; synapse_map overrides the synapse inferred for a given connection.

plot
plot.schematic.PopulationSchematic.plot(
    ax=None,
    layout='stacked',
    glyph='circle',
    node_size=0.7,
    self_loop=(0.62, 0.55),
    coupling_blob=False,
    ellipsis=None,
    legend=True,
    legend_labels=None,
    legend_loc='below',
    synapse_colors=None,
    fontsize=None,
    ranksep=1.15,
    nodesep=1.0,
    hide=None,
    long_range_targets=None,
    fill_width=2.6,
    fit='tight',
    figsize=(7.8, 4.0),
)

Render the schematic onto ax (created if None). Returns the axis.

layout ∈ {stacked, mirror, row}; glyph ∈ {circle, neurons} or a callable(ax, x, y, r, sign, label); self_loop = (height, width) or None; coupling_blob shades a blob between the inner excitatory nodes (mirror layout); ellipsis draws on both ends (defaults to True for stacked with N>1); legend_labels overrides the synapse legend text (e.g. {"AMPA": "AMPA, NMDA"}).

Hiding connections (declare in the figure caption when you do): hide — a predicate callable(Connection) -> bool to drop any connection; and long_range_targets — a convenience restricting long-range projections to those target populations (e.g. ["E"] = E→E only, no FFI, for the spiking Fig 1a view).

Width control (two independent knobs): fill_width (float, default 2.6) stretches the circuit horizontally to at least this width:height aspect (how wide the circuit spreads; None/0 disables); and fit controls how the axes box maps to that circuit — "tight" shrinks the box to the circuit (minimal whitespace, panels may differ in width) · "width" keeps the box’s given width and pads the data limits (panels in a mosaic column stay the SAME width) · a float forces that exact width:height box aspect. Circles stay round in all.

Functions

Name Description
plot_population_schematic Convenience: derive a schematic from dynamics and render it (see PopulationSchematic).

plot_population_schematic

plot.schematic.plot_population_schematic(
    dynamics=None,
    ax=None,
    n_areas=1,
    long_range_synapse='AMPA',
    synapse_map=None,
    **plot_kwargs,
)

Convenience: derive a schematic from dynamics and render it (see PopulationSchematic).