sft_wick.render_style — Visual Style Specifications¶
Backend-agnostic visual styling for Feynman-diagram rendering.
This module defines a hierarchy of frozen dataclasses that capture
what a diagram should look like (colors, line styles, marker
sizes, fonts, layout parameters) without committing to how it
gets drawn. The matplotlib renderer in
sft_wick.drawing and the TikZ/PGF renderer in
sft_wick.drawing_tikz both consume the same
RenderStyle and translate it to backend-native settings.
Three named presets are provided:
default_style()— the colourful on-screen look (blue C, red R) used for quick inspection in notebooks.publication_style()— a cleaner, smaller-marker look with publication-friendly fonts. Honoursusetexif the user has a LaTeX install.grayscale_style()— black/grey palette for printed papers and B&W reproduction.minimal_style()— strips legend / labels / boxes for inset-style use inside a larger figure.
All four call into the same primitives, so users may freely mix
parts (e.g. publication_style().with_overrides(show_legend=False)).
Three label-format flags control the default text of external
vertices (the $\phi_a(\cdot)$ operators):
LABEL_COMPACT—$\phi_a$(no spatial argument). Default.LABEL_FULL—$\phi_a(x_1)$(spatial argument retained — the pre-2026-04 default).LABEL_TIME_F—$\phi_a(t_f)$(substitutet_ffor the spatial argument).
Override these on a per-diagram or per-renderer basis with the
label_format=… constructor argument or the external_labels
keyword on DiagramRenderer.draw().
- class sft_wick.render_style.PropagatorStyle(color, linestyle, linewidth, arrow=False, legend_label='')[source]¶
Bases:
objectVisual style for a single propagator kind (
CorR).- Variables:
color (str) – Stroke colour as a hex string (
"#1f3a5f").linestyle (str) – One of
"solid" | "dashed" | "dotted".linewidth (float) – Line thickness (matplotlib points / TikZ
line width).arrow (bool) – Whether to draw a directed arrowhead (used for R).
legend_label (str) – Text shown in the legend; empty string → no entry.
- Parameters:
- class sft_wick.render_style.NodeStyle(shape, size, fill=True, color='black', edge_color='none')[source]¶
Bases:
objectVisual style for an external point or interaction vertex.
- Variables:
- Parameters:
- class sft_wick.render_style.LabelStyle(fontsize, bold=False, bbox=True, bbox_alpha=0.85, offset_pt=26.0)[source]¶
Bases:
objectVisual style for a label rendered next to a node.
- Variables:
fontsize (float) – Label font size in points.
bold (bool) – If
True, the label is bold.bbox (bool) – If
True, draw a white rounded box behind the label (matplotlib only; TikZ ignores this and lets the user style viaevery label/.styleif desired).bbox_alpha (float) – Opacity of that box.
offset_pt (float) – Distance from the node to the label centre, in typographic points.
- Parameters:
- class sft_wick.render_style.LayoutParams(ext_radius=2.5, spring_k=2.0, spring_iterations=200, spring_seed=42, min_vertex_dist=0.8, margin=0.75, component_gap=1.0, normalize_bbox=True, target_extent=(5.6, 3.6), parallel_edge_curvature=0.6)[source]¶
Bases:
objectNumerical parameters controlling the position-computation step.
These are honoured identically by both backends.
- Variables:
ext_radius (float) – Radius of the circle on which external nodes are placed.
spring_k (float) – Optimal edge length for
spring_layout.spring_iterations (int) – Iteration cap for
spring_layout.spring_seed (int | None) – Seed for
spring_layout(None → non-deterministic).min_vertex_dist (float) – Minimum allowed Euclidean distance between interaction vertices; vertices closer than this are pushed apart in a post-pass.
margin (float) – Padding added to axis limits around the diagram bounding box (matplotlib only).
component_gap (float) – Minimum horizontal gap between disconnected connected components before bbox normalisation. Helps factorised diagrams remain visually separated.
normalize_bbox (bool) – If
True(default), the final layout is re-centred on the origin and uniformly scaled so it fits withintarget_extentwithout distortion. Gives every diagram in a grid roughly the same visual extent — recommended whenever drawing multiple diagrams side by side.target_extent (tuple[float, float]) – Target
(width, height)for the normalised bounding box, in matplotlib units. Default(6.0, 4.0)matches a 4:3 ish aspect-ratio panel.parallel_edge_curvature (float) – Bow strength for parallel edges between the same node pair (matplotlib backend). Each edge in a bundle is drawn as an
arc3withrad = (key - (n-1)/2) * parallel_edge_curvature, so a 2-edge bundle bows by±0.5 ×this value to opposite sides. Larger → fuller arcs. Default0.6(apex offset ≈ 30 % of the chord for a 2-edge bundle).
- Parameters:
- class sft_wick.render_style.RenderStyle(propagators, external_node, vertex_node, external_label, vertex_label, title_fontsize=12.0, suptitle_fontsize=14.0, legend_fontsize=12.0, legend_loc='lower right', show_legend=True, layout=<factory>, rcparams=None, mathtext=True, usetex=False, label_format='compact')[source]¶
Bases:
objectComplete visual specification for a Feynman-diagram render.
Both the matplotlib (
sft_wick.drawing.DiagramRenderer) and the TikZ (sft_wick.drawing_tikz.TikzRenderer) backends consume an instance of this class and translate it to their native style options.Use
default_style(),publication_style(),grayscale_style(), orminimal_style()as a starting point and callwith_overrides()to customise.- Variables:
propagators (collections.abc.Mapping[str, sft_wick.render_style.PropagatorStyle]) – Mapping
{"C": PropagatorStyle, "R": PropagatorStyle}.external_node (sft_wick.render_style.NodeStyle) – Style for external observable nodes.
vertex_node (sft_wick.render_style.NodeStyle) – Style for interaction vertices.
external_label (sft_wick.render_style.LabelStyle) – Style for labels next to external nodes.
vertex_label (sft_wick.render_style.LabelStyle) – Style for labels next to interaction vertices (typically the coupling name).
title_fontsize (float) – Font size of an axes title.
suptitle_fontsize (float) – Font size of the figure-level suptitle.
legend_fontsize (float) – Font size of the propagator-kind legend.
legend_loc (str) – Matplotlib legend location string.
show_legend (bool) – Master toggle for the legend.
layout (sft_wick.render_style.LayoutParams) – Numerical layout parameters.
rcparams (collections.abc.Mapping[str, Any] | None) – Optional mapping fed into a
matplotlib.rc_contextaround the draw call. Useful for serif fonts, math rendering, etc. Ignored by TikZ.mathtext (bool) – If
True, labels are wrapped in$…$so matplotlib renders them as math.usetex (bool) – Convenience flag. When
True, sets"text.usetex": Trueinrcparams(overriding any prior value) — requires a working LaTeX install on the user’s system.label_format (str) – Default external-label format (
LABEL_COMPACTetc.). May be overridden per-call.
- Parameters:
propagators (Mapping[str, PropagatorStyle])
external_node (NodeStyle)
vertex_node (NodeStyle)
external_label (LabelStyle)
vertex_label (LabelStyle)
title_fontsize (float)
suptitle_fontsize (float)
legend_fontsize (float)
legend_loc (str)
show_legend (bool)
layout (LayoutParams)
mathtext (bool)
usetex (bool)
label_format (str)
- propagators: Mapping[str, PropagatorStyle]¶
- external_label: LabelStyle¶
- vertex_label: LabelStyle¶
- layout: LayoutParams¶
- with_overrides(**kwargs)[source]¶
Return a new
RenderStylewith the given top-level fields replaced. Nested fields (propagators["C"].color) needwith_propagator()or manual construction.- Parameters:
kwargs (Any)
- Return type:
- sft_wick.render_style.default_style()[source]¶
The colourful on-screen preset (blue C, red R, square vertices).
Matches the pre-2026-04 visual defaults — use this as the backward-compatible baseline.
- Return type:
- sft_wick.render_style.publication_style(*, usetex=False)[source]¶
Cleaner preset for paper-quality figures.
Smaller, thinner markers, refined palette (slate-blue C, warm-grey R), serif labels via mathtext or LaTeX, compact (no boxed) labels, and a discreet legend. Pass
usetex=Trueif you have a working LaTeX install — otherwise mathtext renders the math.- Parameters:
usetex (bool)
- Return type:
- sft_wick.render_style.grayscale_style()[source]¶
Black-and-white preset.
Distinguishes propagator kinds by line style and arrow-head only; no colour information. Suitable for printed papers and B&W reproduction.
- Return type:
- sft_wick.render_style.minimal_style()[source]¶
Stripped-down preset for inset use.
No legend, no boxes behind labels, no per-axes title. Good when embedding diagrams as small panels inside a larger composite figure.
- Return type:
sft_wick.render_layout — Layout Computation¶
Position computation for Feynman-diagram nodes (backend-agnostic).
This module owns the geometric layout of a FeynmanDiagram:
external nodes are placed on a circle (or, for the common two-external case, mirrored on the x-axis),
interaction vertices are seeded around the origin and refined by
networkx.spring_layoutwith externals pinned,a post-pass enforces a minimum vertex separation,
for two-external layouts, vertices are clamped horizontally so the externals stay outermost.
Both rendering backends (sft_wick.drawing and
sft_wick.drawing_tikz) call compute_layout() and then
translate the resulting positions to their own coordinate
conventions.
The function accepts a manual_positions map so users can pin
arbitrary nodes — particularly useful when the spring layout
produces an aesthetically poor result and the user wants full
control.
- sft_wick.render_layout.compute_layout(diagram, params=LayoutParams(ext_radius=2.5, spring_k=2.0, spring_iterations=200, spring_seed=42, min_vertex_dist=0.8, margin=0.75, component_gap=1.0, normalize_bbox=True, target_extent=(5.6, 3.6), parallel_edge_curvature=0.6), manual_positions=None)[source]¶
Return
{node_id: np.array([x, y])}for every node.- Parameters:
diagram (FeynmanDiagram) – The diagram to lay out.
params (LayoutParams) – Layout parameters (radius, spring-layout knobs, separation thresholds, …).
manual_positions (Mapping[str, tuple[float, float]] | None) – Optional pin map. Any node listed here is placed at the given coordinate and excluded from spring-layout updates. Externals not listed fall back to the circular placement; vertices not listed follow the standard spring + min-distance pipeline.
- Returns:
A dict mapping node-id to a length-2 numpy array. Empty diagrams produce an empty dict; single-node diagrams return one entry at the origin.
- Return type:
- sft_wick.render_layout.neighbor_center(g, node, pos)[source]¶
Centroid of a node’s non-self neighbours, used for self-loop direction.
If the node has no other neighbours, returns a point one unit below it so self-loops on isolated tadpoles point straight up.
- Parameters:
g (MultiGraph)
node (str)
- Return type:
ndarray
sft_wick.render_labels — Label Formatting¶
Label-text generation for Feynman-diagram nodes.
Both rendering backends (matplotlib and TikZ) call into this module to decide what string sits next to each external point and each interaction vertex. Centralising the logic keeps the two backends visually consistent.
The default external label varies with the
LABEL_COMPACT /
LABEL_FULL /
LABEL_TIME_F flag. Users can:
Override individual node labels with the
external_labels/vertex_labelskeyword onsft_wick.drawing.DiagramRenderer.draw().Supply a callable
fn(node_id: str, node_attrs: Mapping) -> stron the renderer constructor for systematic overrides.Keep the default and just switch the format flag globally.
Resolution order, highest priority first:
overrides[node_id] > callable_fn(...) > default_fn(...).
Mathtext / dollar wrapping is the caller’s responsibility for
overrides; the default formatters return strings already wrapped in
$…$ so they render as math in matplotlib.
- sft_wick.render_labels.default_external_label(node_attrs, fmt='compact')[source]¶
Format the default label for an external node.
- Parameters:
- Returns:
A string already wrapped in
$…$for math-mode rendering.- Raises:
ValueError – If
fmtis not one of the recognised formats.- Return type:
- sft_wick.render_labels.default_vertex_label(node_attrs)[source]¶
Format the default label for an interaction vertex.
Wraps the coupling name (e.g.
"F") in$…$. Empty coupling → empty string (no label drawn).
- sft_wick.render_labels.resolve_label(node_id, node_attrs, overrides, callable_fn, default_fn)[source]¶
Pick the best label for a node by checking sources in order.
Priority:
overrides[node_id]>callable_fn(node_id, attrs)>default_fn(attrs).A
Noneor missing entry inoverridesfalls through. A callable returningNonealso falls through (so the callable can opt out for specific nodes).