stormvogel.to_dot¶
Attributes¶
Functions¶
|
Return the lightness-inverted counterpart of hex_color for dark mode. |
|
Collect colors and build dark-mode CSS for an SVG. |
|
Return SVG bytes with the dark-mode |
|
Return an HTML string with the dark-mode |
|
Compute positions for action nodes whose state source has a known position. |
|
Run the graphviz |
|
Return a mapping from each Observation to a muted pastel hex color. |
|
Render a stormvogel model to SVG/PDF using pydot. |
Module Contents¶
- stormvogel.to_dot._NAMED_COLORS¶
- stormvogel.to_dot._invert_lightness(hex_color: str) str¶
Return the lightness-inverted counterpart of hex_color for dark mode.
- stormvogel.to_dot._dark_mode_parts(svg_bytes: bytes) tuple[str, str, str] | None¶
Collect colors and build dark-mode CSS for an SVG.
Returns
(svg_id, style_block, svg_with_id)orNoneif no colors were found. The<style>block is not yet inserted into the SVG so callers can decide whether to inject it inside or outside the<svg>.
- stormvogel.to_dot._dark_mode_svg(svg_bytes: bytes) bytes¶
Return SVG bytes with the dark-mode
<style>injected inside the<svg>.Used for
.svgfile output, where the style must travel with the file.
- stormvogel.to_dot._dark_mode_html(svg_bytes: bytes) str¶
Return an HTML string with the dark-mode
<style>placed outside the SVG.MyST/Sphinx strips
<style>elements from SVG cell outputs but passes HTML outputs through unchanged, so placing the style adjacent to the SVG keeps it intact.
- stormvogel.to_dot._auto_action_positions(model: stormvogel.model.Model, positions: dict, self_loop_radius: float = 0.7, action_radius: float = 0.5, collision_threshold: float = 0.2, perp_offset: float = 0.3) dict¶
Compute positions for action nodes whose state source has a known position.
For regular (non-self-loop) actions the action node is placed at
action_radiusinches from the source state in the direction of the probability-weighted average of target positions. Using a fixed radius (rather than the midpoint) keeps the dot close to its source state, which makes ownership visually unambiguous and avoids the dot landing near or inside a distant target state’s circle.For self-loop actions the action node is placed at
self_loop_radiusinches from the state, cycling through compass angles (below, lower-left, lower-right, …) so that multiple self-loops on the same state do not overlap.After initial placement, action nodes that land within
collision_thresholdinches of each other are spread symmetrically perpendicular to their common direction (same-source) or to the line connecting their source states (different-source), separated byperp_offsetinches.
- stormvogel.to_dot.suggest_positions(model: stormvogel.model.Model, rankdir: str = 'LR', width: float = 0.8, size: str | None = None, ranksep: float | None = None, nodesep: float | None = None) dict¶
Run the graphviz
dotlayout engine on model and return the computed state positions.The returned dict maps each
Stateto an(x, y)tuple (inches) that can be passed directly as thepositionsargument ofplot_model_pydot(). Useful when two models share the same state space and you want both rendered with an identical layout.- Parameters:
model – The model to lay out.
rankdir – Layout direction (“LR”, “TB”, etc.).
width – Diameter of state circles in inches (affects spacing).
size – Optional Graphviz
sizeattribute, e.g."5,3"to cap the layout at 5 × 3 inches. Dot scales the positions down to fit.ranksep – Graphviz
ranksep— minimum distance between ranks (columns in LR layout). Larger values spread the graph horizontally.nodesep – Graphviz
nodesep— minimum distance between nodes in the same rank (rows in LR layout). Larger values spread vertically.
- stormvogel.to_dot._observation_color_map(model: stormvogel.model.Model, saturation: float = 0.4, lightness: float = 0.82) dict¶
Return a mapping from each Observation to a muted pastel hex color.
- stormvogel.to_dot.plot_model_pydot(model: stormvogel.model.Model, output_file: str | None = None, positions: dict | None = None, rankdir: str = 'LR', width: float = 0.8, policy: dict | None = None, state_colors: dict[str, str] | None = None, default_fill: str = '#a6cee3', show_state_rewards: bool = True, show_transition_rewards: bool = True, auto_action_positions: bool = True, highlight_state: stormvogel.model.State | None = None, self_loop_position: str | dict[stormvogel.model.State, str] | None = None, color_by_observation: bool = True) None¶
Render a stormvogel model to SVG/PDF using pydot.
State nodes are circles; action nodes are small filled squares (unlabeled). The edge from a state to an action node carries the action label; edges from an action node to successors carry the probability. DTMCs use direct state-to-state edges instead. The initial state gets an incoming arrow.
- Parameters:
model – The model to render.
output_file – Path ending in .svg or .pdf. None returns an HTML object containing the SVG for display in Jupyter / MyST notebooks.
positions – Optional dict mapping
Stateto(x, y). States without an entry are auto-placed by neato. Action nodes are never required in this dict: when the source state has a known position the action node is placed automatically (midpoint toward target states for regular actions; offset below the state for self-loops). Explicit(State, Action)entries override the automatic placement.rankdir – Layout direction (“LR”, “TB”, etc.); ignored when positions are given (neato is used instead of dot).
width – Diameter of state circles in inches (all states uniform).
policy – Optional dict[State, Action]. The chosen action node and the edge leading to it are highlighted in orange; non-chosen action edges are drawn in a lighter gray.
state_colors – Optional mapping from state label to fill color. The first matching label (in dict-insertion order) determines the fill. States with no matching label use
default_fill.default_fill – Fill color applied to states that have no entry in
state_colors.show_state_rewards – When
True, append state reward values to each state node label. Has no effect if the model has no state rewards.show_transition_rewards – When
True, append transition reward values to the edge label between an action node and its successor. Has no effect if the model has no transition rewards.auto_action_positions – When
True(default), action node positions are computed automatically from state positions. Set toFalseto let the layout engine place all action nodes freely.highlight_state – Optional single state to highlight with a thick orange border. The fill color is still determined by
state_colors/default_fill.self_loop_position – Compass direction(s) controlling where self-loop edges are drawn. A single string (e.g.
"s","ne") applies to all self-loops; adict[State, str]gives per-state control. Bothheadportandtailportare set to the chosen direction.None(default) lets Graphviz decide.color_by_observation – When
True, states are filled with automatically chosen muted pastel colors, one distinct color per observation.state_colors(label-based) still takes priority. Has no effect on models that do not support observations.