logictree package

Submodules

logictree.logicbox module

This module defines the LogicBox class for creating labeled, stylable boxes in logic tree diagrams. Each LogicBox supports custom text, styling, and positioning options using matplotlib’s BoxStyle.

class logictree.logicbox.LogicBox(xpos, ypos, text, box_name, bbox_fc, bbox_ec, font_dict, bbox_style=<matplotlib.patches.BoxStyle.Square object>, lw=1.6, va='center', ha='left', angle=0.0)

Bases: object

A box object for use in logic tree diagrams, containing text and visual styling.

LogicBox provides a labeled, stylable rectangle positioned by its alignment parameters. Boxes can be referenced by name, styled with custom fonts and colors, and later connected by arrows in logic diagrams.

Parameters:
  • xpos (float or int) – X-coordinate of the box, interpreted as the left, center, or right depending on the ha alignment parameter.

  • ypos (float or int) – Y-coordinate of the box, interpreted as the top, center, or bottom depending on the va alignment parameter.

  • text (str) – The text displayed within the box.

  • box_name (str) – A unique identifier for the box; useful for referencing the LogicBox object.

  • bbox_fc (str) – Face color of the box.

  • bbox_ec (str) – Edge color of the box.

  • font_dict (dict) – Dictionary specifying text styling. See https://matplotlib.org/stable/api/text_api.html#matplotlib.text.Text

  • bbox_style (BoxStyle, optional) – Matplotlib BoxStyle object specifying box shape and padding. Default is BoxStyle(“Square”, pad=0.5).

  • lw (float or int, optional) – Line width of the box’s edge. Default is 1.6.

  • va (str, optional) – Vertical alignment, one of [“top”, “center”, “bottom”]. Default is “center”.

  • ha (str, optional) – Horizontal alignment, one of [“left”, “center”, “right”]. Default is “left”.

  • angle (float, optional) – Angle in degrees to rotate your box. Rotations are about the center of the box.

Raises:

ValueError – If va is not one of “top”, “center”, “bottom”, or if ha is not one of “left”, “center”, “right”.

x, y

Coordinates of the box position.

Type:

float

text

Displayed text in the box.

Type:

str

name

Identifier for the box.

Type:

str

face_color

Face color of the box.

Type:

str

edge_color

Edge color of the box.

Type:

str

style

Dictionary of box styling parameters.

Type:

dict

font_dict

Dictionary of text styling parameters.

Type:

dict

va, ha

Vertical and horizontal alignments.

Type:

str

lw

Line width of the box edge.

Type:

float

xLeft, xRight, yBottom, yTop

Coordinates of the box edges, set during layout.

Type:

float or None

width, height

Dimensions of the box, set during layout.

Type:

float or None

xCenter, yCenter

Coordinates of the box center, set during layout.

Type:

float or None

logictree.arrow_etc module

ArrowETC - Custom Arrow Rendering with Vertex-Level Control

This module defines the ArrowETC class, which generates precise, customizable arrows for use in diagrams, flowcharts, technical illustrations, and scientific visualizations. Unlike matplotlib.patches.FancyArrow or FancyArrowPatch, ArrowETC provides full acess and control over the arrow’s geometry, including vertices, segment lengths, and angles.

Arrows can be constructed from straight line segments or smoothed via Bezier interpolation. An optional arrowhead can be appended to the tip and/or tail. All geometry is computed in display (pixel) space and transformed back to data coordinates to ensure accurate rendering under any axis scaling or aspect ratio.

Features

  • Explicit calculation of every polygon vertex, including miter joins at segment corners.

  • Optional Bezier-style curves for smooth arrow shapes.

  • Customizable arrowhead geometry and placement.

  • Compatible with both data-space and pixel-space workflows.

  • Full access to metadata: segment lengths, angles, and vertex coordinates.

  • Optionally close the butt (tail) of the arrow polygon.

Examples

>>> from logictree.ArrowETC import ArrowETC
>>> import matplotlib.pyplot as plt
>>> fig, ax = plt.subplots()
>>> arrow = ArrowETC(ax=ax, path=[(0, 0), (0, 5)], shaft_width=30, arrow_head=True)
>>> arrow.draw_to_ax(ax)
>>> plt.show()
>>> curved = ArrowETC(ax=ax, path=[(0, 0), (2, 4), (4, 0)], shaft_width=25, bezier=True)
>>> curved.save_arrow(name='curved_arrow.png')
class logictree.arrow_etc.ArrowETC(ax, path, shaft_width=20.0, arrow_head=True, arrow_head_at_tail=False, arrow_head_width_multiplier=2, arrow_head_length_multiplier=1.5, ec='grey', fc='white', lw=1.5, ls='-', zorder=100, bezier=False, bezier_n=400, close_tail=True)

Bases: object

A customizable arrow object with explicit control over geometry, styling, and vertex layout.

The ArrowETC class generates straight or curved arrows based on a list of path points. It builds the arrow body polygon in display (pixel) space to ensure consistent appearance across different axis scales and aspect ratios, then transforms it back to data coordinates for plotting.

Arrows can be constructed using straight-line segments or smoothed with a Bezier (B-spline) curve. Optional arrowheads can be added at the tip and/or tail, with configurable width and length multipliers. All geometry and metadata-including vertices, segment lengths, and angles- are accessible after construction.

Parameters:
  • ax (matplotlib.axes.Axes) – The matplotlib Axes instance used to determine coordinate transforms.

  • path (list of tuple[float, float]) – Sequence of (x, y) points defining the arrow path. The first point is the tail, and the last point is the tip.

  • shaft_width (float, optional) – Width of the arrow shaft in pixels. Default is 20.

  • arrow_head (bool, optional) – If True (default), draws an arrowhead at the tip.

  • arrow_head_at_tail (bool, optional) – If True, draws a second arrowhead at the tail (inverted direction). Default is False.

  • arrow_head_width_multiplier (float, optional) – Multiplier controlling how much wider the arrowhead is compared to the shaft. Default is 2.

  • arrow_head_length_multiplier (float, optional) – Multiplier controlling how much longer the arrowhead is compared to the shaft width. Default is 1.5.

  • ec (str, optional) – Edge color of the arrow outline. Default is “grey”.

  • fc (str, optional) – Fill color of the arrow body. Default is “white”.

  • lw (float, optional) – Line width of the arrow edge. Default is 1.5.

  • ls (str, optional) – Line style for the arrow outline (e.g., ‘-’, ‘–‘). Default is “-“.

  • zorder (float, optional) – Drawing order on the plot. Higher values appear on top. Default is 100.

  • bezier (bool, optional) – If True, the path is interpolated as a smooth Bezier (B-spline) curve. Default is False.

  • bezier_n (int, optional) – Number of points used to sample the Bezier curve. Higher values improve smoothness. Default is 400.

  • close_tail (bool, optional) – If True, closes the polygon at the arrow’s tail by connecting the final vertex to the first. Default is True.

path

The input list of (x, y) coordinates defining the arrow path.

Type:

list of tuple[float, float]

path_px

The input list of (x, y) coordinates defining the arrow path after being transformed to display (pixel) space.

Type:

list of tuple[float, float]

x_path

X-coordinates of the path.

Type:

list of float

y_path

Y-coordinates of the path.

Type:

list of float

n_path

Number of path points.

Type:

int

n_segments

Number of segments connecting the path points (n_path - 1).

Type:

int

segment_lengths

Euclidean lengths of each straight segment. None if Bezier is used.

Type:

list of float or None

path_angles

Angle (in radians) each straight segment makes with the x-axis. Undefined for Bezier.

Type:

list of float

vertices

Final arrow polygon vertices in data coordinates.

Type:

np.ndarray of shape (N, 2)

x_vertices

X-coordinates of polygon vertices.

Type:

np.ndarray

y_vertices

Y-coordinates of polygon vertices.

Type:

np.ndarray

draw_to_ax(ax, fill_arrow=True)

Render the arrow polygon onto a specified matplotlib Axes.

This method draws both the filled interior (if fill_arrow=True) and the stroked edge using the styling parameters provided during initialization (fc, ec, lw, ls, and zorder).

Parameters:
  • ax (matplotlib.axes.Axes) – The Axes object on which to render the arrow.

  • fill_arrow (bool, optional) – Whether to fill the interior of the arrow using self.fc. If False, only the outline will be rendered. Default is True.

Returns:

The same Axes object with the arrow drawn onto it.

Return type:

matplotlib.axes.Axes

save_arrow(name='./arrow.png')

Save a standalone image of the arrow to a PNG file.

This method creates a new figure and axes, draws the arrow using internal geometry, and exports the result to the specified file path. The plot is rendered without axes, ticks, or frame, and includes padding to fit the arrow bounds.

Parameters:

name (str, optional) – File path for the saved image. Must end in ‘.png’. Default is ‘./arrow.png’.

Return type:

None

logictree.logictree module

LogicTree - A Flow Diagram Engine for Visual Logic Structures

This module defines the LogicTree class, which provides a high-level interface for creating logic tree diagrams using LogicBox and ArrowETC objects. It supports fast creation of labeled boxes, styled arrow connections (including Bezier curves and segmented paths), and LaTeX-enhanced text rendering. Diagrams are rendered with matplotlib, and the resulting figures can be saved as high-resolution images.

Features

  • Add boxes with custom text, alignment, rotation, and visual styling.

  • Connect boxes using straight, segmented, or curved arrows with optional arrowheads.

  • Full support for LaTeX rendering inside boxes and titles.

  • Export to PNG with tight layout control and adjustable aspect ratio.

Examples

>>> from logictree.LogicTreeETC import LogicTree
>>> logic_tree = LogicTree(xlims=(0, 100), ylims=(0, 100), title="My Logic Tree")

# Add boxes >>> logic_tree.add_box(20, 80, “Start”, “Start”, “black”, “white”, ha=”center”) >>> logic_tree.add_box(20, 50, “Decision”, “Decision”, “black”, “white”, ha=”center”) >>> logic_tree.add_box(10, 20, “Option A”, “OptionA”, “black”, “green”, ha=”center”) >>> logic_tree.add_box(30, 20, “Option B”, “OptionB”, “black”, “red”, ha=”center”)

# Add arrows >>> logic_tree.add_connection( … logic_tree.boxes[“Start”], logic_tree.boxes[“Decision”], arrow_head=True, shaft_width=25 … ) >>> logic_tree.add_connection_biSplit( … logic_tree.boxes[“Decision”], … logic_tree.boxes[“OptionA”], … logic_tree.boxes[“OptionB”], … arrow_head=True, shaft_width=30 … )

# Finalize and save >>> logic_tree.make_title(pos=”center”) >>> logic_tree.save_as_png(“logic_tree_example.png”, dpi=300)

Notes

  • If LaTeX rendering is enabled, you must have packages such as bm, amsmath, soul, and relsize installed. On most Linux systems, these can be installed using:

    sudo apt install -y texlive-latex-base texlive-latex-recommended texlive-fonts-recommended

    texlive-latex-extra texlive-humanities dvipng cm-super

class logictree.logictree.LogicTree(fig_size=(9, 9), xlims=(0, 100), ylims=(0, 100), colormode='light', title=None, font_dict=None, font_dict_title=None, text_color=None, title_color=None)

Bases: object

LogicTree - High-Level Diagram Layout Engine for Visualizing Logic Structures

The LogicTree class provides a complete system for building logic diagrams by placing labeled boxes (LogicBox objects) and connecting them with highly customizable arrows (ArrowETC objects). It abstracts away most of the layout, rendering, and styling logic, while remaining fully compatible with the matplotlib workflow.

Key features include: - Flexible arrow routing (straight, segmented, or curved paths) - Optional arrowhead placement and geometry control - Box labeling with alignment, LaTeX rendering, and font customization - Tight integration with matplotlib for exporting high-resolution plots

Parameters:
  • fig_size (tuple of float, optional) – Size of the output matplotlib figure in inches (width, height). Default is (9, 9).

  • xlims (tuple of float, optional) – Min and max limits of the x-axis. Used to constrain box layout. Default is (0, 100).

  • ylims (tuple of float, optional) – Min and max limits of the y-axis. Default is (0, 100).

  • colormode ({'dark', 'light'}, optional) – Sets default font and figure background colors. Default is ‘light’.

  • title (str, optional) – Title of the logic diagram. Can also be set later using make_title().

  • font_dict (dict, optional) – Dictionary of font properties to use for box text. If None, a default style is used.

  • font_dict_title (dict, optional) – Dictionary of font properties to use for the figure title. If None, a default style is used.

  • text_color (str, optional) – Override for all box text color (applies to font_dict if provided).

  • title_color (str, optional) – Override for the title color (applies to font_dict_title if provided).

fig

The main matplotlib figure object.

Type:

matplotlib.figure.Figure

ax

The axes object where boxes and arrows are drawn.

Type:

matplotlib.axes.Axes

boxes

Dictionary of box name → LogicBox instances. Populated via add_box().

Type:

dict[str, LogicBox]

arrows

List of all ArrowETC arrows added to the figure.

Type:

list[ArrowETC]

title

Title string used for rendering the figure heading.

Type:

str or None

xlims, ylims

Axis limits, controlling visual boundaries.

Type:

tuple of float

font_dict

Default font properties for box text.

Type:

dict

title_font_dict

Font properties used when rendering the diagram title.

Type:

dict

latex_ul_depth

Thickness setting used when underlining LaTeX-rendered box text.

Type:

str

latex_ul_width

Depth setting used when underlining LaTeX-rendered box text.

Type:

str

add_arrow(arrow, fill_arrow=True)

Add a preconstructed ArrowETC object to the LogicTree figure.

This method allows manual control over arrow creation by letting you construct an ArrowETC instance externally and then add it to the tree. Useful for advanced customizations or layout debugging.

The arrow is appended to self.arrows and drawn onto the existing matplotlib Axes.

Parameters:
  • arrow (ArrowETC) – A fully constructed ArrowETC object with geometry and styling already defined.

  • fill_arrow (bool, optional) – Whether to fill the arrow body (ArrowETC.fc). If False, only the outline is drawn. Default is True.

Raises:

ValueError – If the arrow has fewer than two path points.

Return type:

None

add_arrow_between(start, end, shaft_width=20, arrow_head=True, arrow_head_at_tail=False, arrow_head_width_multiplier=2, arrow_head_length_multiplier=1.5, tip_offset=0.0, butt_offset=0.0, fc='black', ec='black', zorder=1.0, lw=1.0, ls='-', fill_arrow=True)

Draw a single arrow between two points using ArrowETC.

This low-level method is ideal for freeform annotations, callouts, or diagram embellishments. Arrow geometry is computed between two (x, y) coordinates with optional tip and butt offsets.

Parameters:
  • start (tuple of float) – (x, y) coordinates for the arrow base (tail).

  • end (tuple of float) – (x, y) coordinates for the arrow tip (head).

  • shaft_width (float, optional) – Width of the arrow shaft in pixels. Default is 20.

  • arrow_head (bool, optional) – Whether to draw an arrowhead at the tip. Default is True.

  • arrow_head_at_tail (bool, optional) – Whether to draw a second arrowhead pointing backward from the tail. Default is False.

  • arrow_head_width_multiplier (float, optional) – Width multiplier for arrowhead relative to shaft. Default is 2.

  • arrow_head_length_multiplier (float, optional) – Length multiplier for arrowhead relative to shaft width. Default is 1.5.

  • tip_offset (float, optional) – Distance to shorten the arrow tip, to avoid overlapping a target. Default is 0.0.

  • butt_offset (float, optional) – Distance to push the arrow base forward, away from its start point. Default is 0.0.

  • fc (str, optional) – Fill color of the arrow. Default is “black”.

  • ec (str, optional) – Edge (stroke) color of the arrow. Default is “black”.

  • zorder (float, optional) – Drawing order for the arrow. Higher values appear on top. Default is 1.0.

  • lw (float, optional) – Line width for the arrow outline. Default is 1.0.

  • ls (str, optional) – Line style for the outline (e.g., “-”, “–“). Default is “-“.

  • fill_arrow (bool, optional) – Whether to fill the interior of the arrow. Default is True.

Raises:

ValueError – If the start and end points are identical (zero-length arrow).

Return type:

None

add_bezier_connection(boxA, boxB, style='smooth', control_points=None, arrow_head=True, arrow_head_width_multiplier=2, arrow_head_length_multiplier=1.5, shaft_width=20, fill_connection=True, fc=None, ec=None, lw=0.7, sideA=None, sideB=None, butt_offset=0, tip_offset=0, n_bezier=600)

Draw a curved arrow between two boxes or from a box to a coordinate using a smooth Bezier curve.

This method builds a flowing, organic connection path ideal for reducing visual clutter in dense diagrams. Curvature is determined automatically using a spline fit through inferred or specified side coordinates.

Parameters:
  • boxA (LogicBox) – The source box where the arrow begins.

  • boxB (LogicBox or tuple of float) – The destination - either another LogicBox or a fixed (x, y) coordinate.

  • arrow_head (bool, optional) – Whether to include an arrowhead at the tip. Default is True.

  • arrow_head_at_tail (bool, optional) – Whether to draw an arrowhead pointing backward from the tail. Default is False.

  • arrow_head_width_multiplier (float, optional) – Width multiplier for the arrowhead. Default is 2.

  • arrow_head_length_multiplier (float, optional) – Length multiplier for the arrowhead. Default is 1.5.

  • shaft_width (float, optional) – Width of the arrow shaft in pixels. Default is 20.

  • fill_connection (bool, optional) – Whether to fill the arrow polygon. Default is True.

  • butt_offset (float, optional) – Distance to offset the base of the arrow away from the source box. Default is 0.

  • tip_offset (float, optional) – Distance to offset the arrow tip away from the destination. Useful to avoid overlap. Default is 0.

  • fc (str, optional) – Fill color of the arrow body. If None, inherits from destination box (if applicable).

  • ec (str, optional) – Edge color of the arrow outline. If None, inherits from destination box.

  • lw (float, optional) – Line width for the arrow outline. Default is 0.7.

  • bezier_n (int, optional) – Number of points used to sample the Bezier curve. Higher values yield smoother curves. Default is 400.

  • sideA (str, optional) – Edge or corner of boxA to connect from. Default is inferred from angle.

  • sideB (str, optional) – Edge or corner of boxB to connect to. Ignored if boxB is a coordinate.

Raises:

ValueError – If box coordinates are uninitialized or the curve cannot be constructed.

Return type:

None

add_box(xpos, ypos, text, box_name, bbox_fc, bbox_ec, font_dict=None, text_color=None, fs=None, font_weight=None, lw=1.6, bbox_style=<matplotlib.patches.BoxStyle.Round object>, va='center', ha='right', use_tex_rendering=False, ul=False, ul_depth_width=None, angle=0.0)

Add a styled LogicBox to the diagram at the specified position.

This method places a new labeled box on the logic tree, using customizable styling for fonts, alignment, and appearance. Optionally, LaTeX rendering and underlining can be enabled for rich formatting.

Parameters:
  • xpos (float) – Coordinates for box placement in data space.

  • ypos (float) – Coordinates for box placement in data space.

  • text (str) – Text to display inside the box. Can include LaTeX if use_tex_rendering=True.

  • box_name (str) – Unique identifier for the box. Used to reference the box in connections.

  • bbox_fc (str) – Face color and edge color of the box. Accepts color names or RGBA values.

  • bbox_ec (str) – Face color and edge color of the box. Accepts color names or RGBA values.

  • font_dict (dict, optional) – Dictionary of font properties (e.g., fontname, fontsize, weight).

  • text_color (str, optional) – Override for the text color (applied to font_dict).

  • fs (int, optional) – Override for font size.

  • font_weight (float or str, optional) – Font weight (e.g., ‘bold’, ‘normal’).

  • lw (float, optional) – Line width of the box outline. Default is 1.6.

  • bbox_style (matplotlib.patches.BoxStyle, optional) – Shape and padding style for the box. Default is BoxStyle(“Round”, pad=0.6).

  • va ({'top', 'center', 'bottom'}, optional) – Vertical alignment of text within the box. Default is ‘center’.

  • ha ({'left', 'center', 'right'}, optional) – Horizontal alignment of text. Default is ‘right’.

  • use_tex_rendering (bool, optional) – If True, enables LaTeX rendering for the box text. Requires proper LaTeX installation.

  • ul (bool, optional) – If True, applies underlining to the box text using LaTeX.

  • ul_depth_width (tuple of (float, float), optional) – Tuple specifying LaTeX underline depth and thickness.

  • angle (float, optional) – Angle (in degrees) to rotate the box around its center. Default is 0.

Returns:

The constructed and registered LogicBox object.

Return type:

LogicBox

Raises:

ValueError – If box_name is already used or if the rendered text lacks a valid bounding box.

add_connection(boxA, boxB, segmented=False, arrow_head=True, arrow_head_at_tail=False, arrow_head_width_multiplier=2, arrow_head_length_multiplier=1.5, shaft_width=20, fill_connection=True, butt_offset=0, tip_offset=0, fc=None, ec=None, lw=0.7, sideA=None, sideB=None)

Draw a straight or elbow-style arrow between two boxes or from a box to a point.

This method provides full control over routing, arrowhead style, and shaft offsets. It supports both direct and segmented paths and allows entry/exit points on specific box edges or corners.

Parameters:
  • boxA (LogicBox) – The source box where the arrow begins.

  • boxB (LogicBox or tuple of float) – The destination - either another LogicBox or a fixed (x, y) coordinate.

  • segmented (bool, optional) – If True, draws an elbow-style arrow with horizontal/vertical joints. If False, draws a straight line. Default is False.

  • arrow_head (bool, optional) – Whether to include an arrowhead pointing at the destination. Default is True.

  • arrow_head_at_tail (bool, optional) – Whether to include a second arrowhead pointing backward from the source. Default is False.

  • arrow_head_width_multiplier (float, optional) – Width multiplier for the arrowhead. Default is 2.

  • arrow_head_length_multiplier (float, optional) – Length multiplier for the arrowhead. Default is 1.5.

  • shaft_width (float, optional) – Thickness of the arrow shaft in pixels. Default is 20.

  • fill_connection (bool, optional) – Whether to fill the arrow polygon with color. Default is True.

  • butt_offset (float, optional) – Offset the arrow’s base outward from the source box. Default is 0.

  • tip_offset (float, optional) – Offset the arrow’s tip away from the target. Helps avoid overlap. Default is 0.

  • fc (str, optional) – Fill color for the arrow body. If None, uses the target box’s face color.

  • ec (str, optional) – Edge (outline) color. If None, uses the target box’s edge color.

  • lw (float, optional) – Line width for the arrow outline. Default is 0.7.

  • sideA (str, optional) – Edge or corner of boxA to start from. If None, inferred based on angle.

  • sideB (str, optional) – Edge or corner of boxB to point to. Ignored if boxB is a coordinate.

Raises:

ValueError – If box coordinates are missing or if the boxes have identical centers.

Return type:

None

add_connection_biSplit(boxA, boxB, boxC, arrow_head=True, shaft_width=20, fill_connection=True, fc_A=None, ec_A=None, fc_B=None, ec_B=None, fc_C=None, ec_C=None, lw=0.5, butt_offset=0, tip_offset=0, textLeft=None, textRight=None, textLeftOffset='above', textRightOffset='above', text_kwargs=None)

Draw a bifurcating arrow connection from a parent box (boxA) to two child boxes (boxB, boxC).

This method creates a split connection: a single vertical shaft from boxA that branches into two lateral arrows, one for each child. Labels can optionally be placed along each branch.

Left/right ordering is automatically inferred based on the horizontal positions of boxB and boxC. Vertical direction (upward vs. downward) is inferred from the y-position of boxA relative to the children.

Parameters:
  • boxA (LogicBox) – The parent box initiating the bifurcation.

  • boxB (LogicBox) – One child box. Its left/right role is automatically determined.

  • boxC (LogicBox) – The other child box.

  • arrow_head (bool, optional) – Whether to draw arrowheads on both branches. Default is True.

  • shaft_width (float, optional) – Width of the arrow shafts in pixels. Default is 20.

  • fill_connection (bool, optional) – Whether to fill the arrows with color (fc_*). Default is True.

  • fc_A (str, optional) – Face and edge colors for the vertical stem from boxA. If None, defaults to boxA’s colors. Use “ec” or “fc” to inherit from the complementary color.

  • ec_A (str, optional) – Face and edge colors for the vertical stem from boxA. If None, defaults to boxA’s colors. Use “ec” or “fc” to inherit from the complementary color.

  • fc_B (str, optional) – Colors for the branch leading to boxB. Same logic as above.

  • ec_B (str, optional) – Colors for the branch leading to boxB. Same logic as above.

  • fc_C (str, optional) – Colors for the branch leading to boxC.

  • ec_C (str, optional) – Colors for the branch leading to boxC.

  • lw (float, optional) – Line width for arrow outlines. Default is 0.5.

  • butt_offset (float, optional) – Distance to nudge the stem away from boxA. Default is 0.

  • tip_offset (float, optional) – Distance to nudge the arrow tips away from the target boxes. Default is 0.

  • textLeft (str, optional) – Optional labels placed along the left and right arrow branches.

  • textRight (str, optional) – Optional labels placed along the left and right arrow branches.

  • textLeftOffset ({'above', 'below'}, optional) – Whether to place the corresponding label above or below its arrow shaft. Default is ‘above’.

  • textRightOffset ({'above', 'below'}, optional) – Whether to place the corresponding label above or below its arrow shaft. Default is ‘above’.

  • text_kwargs (dict, optional) –

    Additional text styling options for labels, e.g.:
    • fontsize : int

    • fontname : str

    • color : str

    • fontstyle : str

Raises:

ValueError – If any of the boxes are missing layout attributes. If boxA is not clearly above or below both boxB and boxC.

Notes

Return type:

None

This method is useful for visualizing binary decisions or logical forks in flow diagrams. Each arrow path consists of three segments: vertical stem → horizontal split → vertical drop.

make_title(pos='left', consider_box_x=True, new_title=None)

Place a title above the LogicTree figure with optional alignment and dynamic layout positioning.

This method adds a title to the top of the logic tree using the tree’s bounding boxes (if consider_box_x=True) or the full axis limits otherwise. Title alignment can be left, center, or right. You may also provide a new title string inline.

Parameters:
  • pos ({'left', 'center', 'right'}, optional) – Horizontal alignment of the title. Default is ‘left’.

  • consider_box_x (bool, optional) – If True (default), aligns the title based on LogicBox horizontal positions; otherwise uses xlims from the Axes.

  • new_title (str, optional) – If given, replaces the current self.title string with this value before placing it.

Raises:
  • ValueError – If pos is invalid.

  • ValueError – If self.title is None when rendering the title.

  • ValueError – If any LogicBox lacks xLeft or xRight coordinates when consider_box_x=True.

Return type:

None

save_as_png(file_name, dpi=800, bbox_inches='tight', content_padding=0.0, aspect='equal')

Export the LogicTree diagram as a high-resolution PNG image.

Saves the current figure with optional DPI, padding, and aspect ratio control. Useful for publication or presentation-quality outputs.

Parameters:
  • file_name (str) – Full path and name of the output PNG file.

  • dpi (int, optional) – Resolution of the output image in dots per inch. Default is 800.

  • bbox_inches ({'tight'} or None, optional) – Whether to automatically crop whitespace around the figure. Default is “tight”.

  • content_padding (float, optional) – Padding (in inches) around the figure content. Helps avoid clipped labels or boxes.

  • aspect ({'auto', 'equal'}, optional) – Axes aspect ratio mode. Default is ‘equal’.

Return type:

None

logictree.vector_detector module

VectorML: A lightweight feature point detection module for annotated vector graphics.

This module defines the VectorDetector class, which allows users to extract, map, and label salient image features (e.g., corners or vertices) using OpenCV’s Harris and Shi-Tomasi algorithms. It supports visualization of raw and labeled points, and rescaling coordinates to match extent-based data axes used in matplotlib.

Typical use case:
  • Load an image using matplotlib.image.imread or cv2.imread

  • Initialize a VectorDetector with the image and optional extent

  • Call detect_features() to find candidate points

  • Use plot_detected_points() to visualize the detected points

  • Retroactively label points by using label_point()

  • Use plot_labeled_points() for visualizing just your labeled points

  • Access labeled points by calling get_point_by_label()

Example

```python import matplotlib.image as mpimg from logictree.VectorML import VectorDetector

# Load image and create detector img = mpimg.imread(“nephron_diagram.png”) detector = VectorDetector(img, extent=(0, 100, 0, 100))

# Detect features using Shi-Tomasi detector.detect_features(method=”shi-tomasi”, max_points=50)

# Label a few key points detector.label_point(0, “glomerulus_center”) detector.label_point(5, “loop_of_Henle_tip”)

# Save annotated image detector.plot_detected_points(“outputs/all_detected.png”) detector.plot_labeled_points(“outputs/labeled_points.png”) ```

class logictree.vector_detector.VectorDetector(image, extent=None)

Bases: object

Detects feature points (vertices of interest) from a grayscale or color image using OpenCV. Automatically maps detected coordinates to a user-defined extent used in matplotlib imshow().

original_image

The input image in RGB or grayscale.

Type:

np.ndarray

gray

Grayscale version of the input image, normalized to uint8.

Type:

np.ndarray

extent

Image extent in the form (x0, x1, y0, y1) to map pixel coordinates to data space.

Type:

Optional[tuple[float, float, float, float]]

points

List of detected (x, y) coordinates, optionally mapped to extent.

Type:

list[tuple[float, float]]

labels

Mapping from user-defined string labels to detected coordinates.

Type:

dict[str, tuple[float, float]]

detect_features(method='harris', max_points=100, quality=0.01, min_distance=10.0, mask_border=0)

Detects feature points from the image using the specified method.

Parameters:
  • method ({'harris', 'shi-tomasi'}) – Corner detection algorithm to use.

  • max_points (int) – Maximum number of feature points to return.

  • quality (float) – Quality level threshold (used in Shi-Tomasi).

  • min_distance (float) – Minimum spacing between detected features (used in Shi-Tomasi).

  • mask_border (int) – If > 0, masks out a border of pixels around the image to reduce noisy edge detection.

Return type:

None

get_point_by_label(label)

Retrieves the coordinates of a labeled point.

Parameters:

label (str) – The user-defined label assigned to a point.

Returns:

The (x, y) coordinates of the labeled point, or None if the label is not found.

Return type:

tuple[float, float] or None

label_point(index, label)

Assigns a label to a previously detected point by index.

Parameters:
  • index (int) – The index of the detected point in self.points.

  • label (str) – A user-defined string label to assign to the selected point.

Raises:

IndexError – If the provided index is out of range for the list of detected points.

Return type:

None

list_labeled_points()

Returns a dictionary of all user-labeled points.

Returns:

A copy of the internal label-to-point mapping.

Return type:

dict[str, tuple[float, float]]

plot_detected_points(save_path)

Visualizes all detected feature points with numeric labels and saves the plot.

Parameters:

save_path (str | Path) – File path where the output figure will be saved (e.g., ‘outputs/all_detected.png’).

Return type:

None

Notes

Each detected point is colored and numbered in the colorbar legend. The image background will reflect the original image with optional extent mapping.

plot_labeled_points(save_path, legend_loc='best')

Plots only the points that have been user-labeled and saves the image.

Parameters:
  • save_path (str | Path) – File path where the output figure will be saved (e.g., ‘outputs/labeled_points.png’).

  • legend_loc (str, optional) – Location of the legend in the plot. Defaults to “best”.

Return type:

None

Notes

Each labeled point is assigned a color and displayed with its label in the legend.