pylinkage.visualizer package
Submodules
pylinkage.visualizer.animated module
The visualizer module makes visualization of linkages easy using matplotlib.
Created on Mon Jun 14, 12:13:58 2021.
@author: HugoFara
- pylinkage.visualizer.animated.plot_kinematic_linkage(linkage: Linkage, fig: Figure, axis: Axes, loci: Sequence[tuple[Coord, ...]], frames: int = 100, interval: float = 40) FuncAnimation
Plot a linkage with an animation.
- Args:
linkage: The linkage to animate. fig: Figure to support the axes. axis: The subplot to draw on. loci: list of list of coordinates. frames: Number of frames to draw the linkage on. interval: Delay between frames in milliseconds.
- Returns:
The animation object.
- pylinkage.visualizer.animated.show_linkage(linkage: Linkage, save: bool = False, prev: Sequence[Coord] | None = None, loci: Sequence[tuple[Coord, ...]] | None = None, points: int = 100, iteration_factor: float = 1, title: str | None = None, duration: float = 5, fps: int = 24) FuncAnimation
Display results as an animated drawing.
- Args:
linkage: The Linkage you want to draw. save: To save the animation. prev: Previous coordinates to use for linkage. loci: list of loci. points: Number of points to draw for a crank revolution.
Useless when loci are set.
- iteration_factor: A simple way to subdivide the movement. The real
number of points will be points * iteration_factor.
title: Figure title. Defaults to str(len(ani)). duration: Animation duration (in seconds). fps: Number of frames per second for the output video.
- Returns:
The animation object.
- pylinkage.visualizer.animated.swarm_tiled_repr(linkage: Linkage, swarm: tuple[int, Sequence[tuple[float, np.ndarray, Sequence[Coord]]]], fig: Figure, axes: np.ndarray, dimension_func: Callable[[np.ndarray], Sequence[float]] | None = None, points: int = 12, iteration_factor: float = 1) None
Show all the linkages in a swarm in tiled mode.
- Args:
linkage: The original Linkage that will be MODIFIED. swarm: Tuple of (iteration_number, list_of_agents) where each agent is
(score, dimensions, initial_positions).
fig: Figure to support the axes. axes: The subplot to draw on. points: Number of steps to use for each Linkage. iteration_factor: A simple way to subdivide the movement. The real
number of points will be points * iteration_factor.
- dimension_func: If you want a special formatting of dimensions from
agents before passing them to the linkage.
- pylinkage.visualizer.animated.update_animated_plot(linkage: Linkage, index: int, images: list[Line2D], loci: Sequence[tuple[Coord, ...]]) list[Line2D]
Modify im, instead of recreating it to make the animation run faster.
- Args:
linkage: The linkage being animated. index: Frame index. images: Artist to be modified. loci: list of loci.
- Returns:
Updated version of images.
pylinkage.visualizer.core module
Core features for visualization.
This module provides shared utilities for matplotlib-based visualization. For symbol definitions used by other backends (Plotly, drawsvg), see symbols.py.
pylinkage.visualizer.static module
Static (not animated) visualization.
- pylinkage.visualizer.static.plot_static_linkage(linkage: Linkage, axis: Axes, loci: Iterable[tuple[Coord, ...]], locus_highlights: list[list[Coord]] | None = None, show_legend: bool = False) None
Plot a linkage without movement.
- Args:
linkage: The linkage you want to see. axis: The graph we should draw on. loci: List of list of coordinates. They will be plotted. locus_highlights: If a list, should be a list of list of coordinates you
want to see highlighted.
show_legend: To add an automatic legend to the graph.
Module contents
Linkage visualization features.
- Backends:
matplotlib (default): plot_static_linkage, plot_kinematic_linkage, show_linkage
plotly: plot_linkage_plotly, animate_linkage_plotly (interactive HTML)
drawsvg: plot_linkage_svg, save_linkage_svg (publication-quality SVG)
dxf: plot_linkage_dxf, save_linkage_dxf (CAD/CNC export)
step: build_linkage_3d, save_linkage_step (3D CAD interchange)
- class pylinkage.visualizer.JointProfile(radius: float, length: float)
Bases:
objectProfile for 3D joint geometry.
- Attributes:
radius: Pin/hole radius in world units. length: Pin length in z-direction.
- length: float
- radius: float
- class pylinkage.visualizer.LinkProfile(width: float, thickness: float, fillet_radius: float = 0.0)
Bases:
objectCross-section profile for 3D links.
- Attributes:
width: Width of the link bar in world units. thickness: Thickness (z-direction) in world units. fillet_radius: Radius for edge rounding (0 for sharp edges).
- fillet_radius: float = 0.0
- thickness: float
- width: float
- class pylinkage.visualizer.LinkStyle(value)
Bases:
EnumVisual styles for drawing links between joints.
- BAR = 1
- BONE = 2
- LINE = 3
- class pylinkage.visualizer.SymbolType(value)
Bases:
EnumTypes of kinematic symbols.
- CRANK = 3
- FIXED = 5
- GROUND = 1
- LINEAR = 6
- REVOLUTE = 2
- SLIDER = 4
- pylinkage.visualizer.animate_dashboard(linkage: Linkage, history: History, dim_names: Sequence[str], dim_types: Sequence[str] | None = None, bounds: tuple[Sequence[float], Sequence[float]] | None = None, dimension_func: Callable[[np.ndarray], Sequence[float]] | None = None, interval: int = 500, save_path: str | None = None) FuncAnimation
Animate the dashboard layout over optimization history.
- Args:
linkage: The linkage being optimized. history: List of swarms, one per iteration. dim_names: Names for each dimension. dim_types: Type of each dimension (‘length’ or ‘angle’). bounds: Optional (min_bounds, max_bounds). dimension_func: Optional function to transform dimensions. interval: Delay between frames in milliseconds. save_path: If provided, save animation to this path.
- Returns:
The animation object.
- pylinkage.visualizer.animate_kinematics(linkage: Linkage, *, show_velocity: bool = True, show_acceleration: bool = False, velocity_scale: float | None = None, fps: int = 24, duration: float = 5.0, figsize: tuple[float, float] = (12, 8), title: str | None = None, save_path: str | None = None) Figure
Create an animated visualization with velocity vectors.
- Args:
linkage: The linkage to visualize. show_velocity: Whether to show velocity vectors. show_acceleration: Whether to show acceleration vectors. velocity_scale: Arrow scale for velocities. Auto-computed if None. fps: Frames per second. duration: Animation duration in seconds. figsize: Figure size (width, height) in inches. title: Figure title. save_path: If provided, save animation to this path (e.g., “animation.gif”).
- Returns:
The matplotlib Figure object.
- Example:
>>> linkage.set_input_velocity(crank, omega=10.0) >>> fig = animate_kinematics(linkage, show_velocity=True, save_path="vel.gif")
- pylinkage.visualizer.animate_linkage_plotly(linkage: Linkage, loci: Iterable[tuple[Coord, ...]] | None = None, *, title: str | None = None, show_loci: bool = True, width: int = 900, height: int = 700, frame_duration: int = 50) Figure
Create an animated Plotly diagram with play/pause controls.
- Args:
linkage: The linkage to visualize. loci: Optional precomputed loci. If None, runs simulation. title: Optional title for the diagram. show_loci: Whether to show joint movement paths. width: Figure width in pixels. height: Figure height in pixels. frame_duration: Milliseconds per frame.
- Returns:
A plotly Figure object with animation.
- pylinkage.visualizer.animate_parallel_coordinates(history: History, dim_names: Sequence[str], dim_types: Sequence[str] | None = None, bounds: tuple[Sequence[float], Sequence[float]] | None = None, interval: int = 200, cmap: str = 'viridis', save_path: str | None = None) FuncAnimation
Animate parallel coordinates plot over optimization history.
- Args:
history: List of swarms, one per iteration. dim_names: Names for each dimension. dim_types: Type of each dimension (‘length’, ‘angle’, or ‘score’). bounds: Optional (min_bounds, max_bounds) for normalization. interval: Delay between frames in milliseconds. cmap: Colormap name. save_path: If provided, save animation to this path.
- Returns:
The animation object.
- pylinkage.visualizer.build_linkage_3d(linkage: Linkage, loci: Iterable[tuple[Coord, ...]] | None = None, *, frame_index: int = 0, link_profile: LinkProfile | None = None, joint_profile: JointProfile | None = None, z_offset: float = 0.0, include_pins: bool = True) Any
Build a 3D CAD model of the linkage.
Creates a build123d Compound containing all links and joint pins as separate solids for the specified frame position.
- Args:
linkage: The linkage to model. loci: Optional precomputed loci. If None, runs simulation. frame_index: Which simulation frame to export (0 = first). link_profile: Cross-section dimensions for links. Auto-scaled if None. joint_profile: Dimensions for joint pins/holes. Auto-scaled if None. z_offset: Base Z position for the linkage. include_pins: Whether to model joint pins as separate parts.
- Returns:
A build123d Compound with all parts.
- Example:
>>> from pylinkage.visualizer import build_linkage_3d, save_linkage_step >>> model = build_linkage_3d(linkage) >>> model.export_step("linkage.step")
- pylinkage.visualizer.dashboard_layout(linkage: Linkage, swarm: Swarm, score_history: Sequence[float], dim_names: Sequence[str], dim_types: Sequence[str] | None = None, bounds: tuple[Sequence[float], Sequence[float]] | None = None, dimension_func: Callable[[np.ndarray], Sequence[float]] | None = None, fig: Figure | None = None) Figure
Create a dashboard layout for PSO visualization.
Layout: +—————–+——————+ | Score History | Best Linkage | | (line plot) | (static plot) | +—————–+——————+ | Length Params | Angle Params | | (box plot) | (polar/circular) | +—————–+——————+
- Args:
linkage: The linkage being optimized (will be modified). swarm: Current swarm state. score_history: History of best scores per iteration. dim_names: Names for each dimension. dim_types: Type of each dimension (‘length’ or ‘angle’). bounds: Optional (min_bounds, max_bounds). dimension_func: Optional function to transform dimensions. fig: Existing figure to use.
- Returns:
The matplotlib Figure object.
- pylinkage.visualizer.parallel_coordinates_plot(swarm: Swarm, dim_names: Sequence[str], dim_types: Sequence[str] | None = None, bounds: tuple[Sequence[float], Sequence[float]] | None = None, ax: Axes | None = None, cbar_ax: Axes | None = None, cmap: str = 'viridis', alpha: float = 0.3, highlight_best: int = 5) Axes
Create a parallel coordinates plot for a PSO swarm.
Each dimension gets its own vertical axis, normalized to [0, 1]. Particles are colored by their score (fitness).
- Args:
- swarm: Tuple of (iteration, list_of_agents) where each agent is
(score, dimensions, initial_positions).
dim_names: Names for each dimension. dim_types: Type of each dimension (‘length’, ‘angle’, or ‘score’).
Used for axis grouping and labeling.
bounds: Optional (min_bounds, max_bounds) for normalization. ax: Matplotlib axes to plot on. If None, creates new figure. cbar_ax: Optional axes for the colorbar. If provided, colorbar is
drawn there instead of stealing space from ax. Use this for animations to prevent layout shifts.
cmap: Colormap name for score coloring. alpha: Line transparency for regular particles. highlight_best: Number of best particles to highlight.
- Returns:
The matplotlib Axes object.
- pylinkage.visualizer.plot_acceleration_vectors(linkage: Linkage, axis: Axes, positions: NDArray[np.float64] | Sequence[tuple[float, float]], accelerations: NDArray[np.float64] | Sequence[tuple[float, float]], *, scale: float = 0.01, color: str = 'red', width: float = 0.004, label: str = 'Acceleration', skip_static: bool = True) Quiver
Plot acceleration vectors as arrows at joint positions.
- Args:
linkage: The linkage being visualized. axis: Matplotlib axes to draw on. positions: Joint positions, shape (n_joints, 2) or list of (x, y). accelerations: Joint accelerations, shape (n_joints, 2) or list of (ax, ay). scale: Scaling factor for arrow length. Smaller = longer arrows. color: Arrow color. width: Arrow shaft width as fraction of plot width. label: Legend label for the arrows. skip_static: Whether to skip drawing arrows for static joints.
- Returns:
The Quiver object for further customization.
- pylinkage.visualizer.plot_kinematic_linkage(linkage: Linkage, fig: Figure, axis: Axes, loci: Sequence[tuple[Coord, ...]], frames: int = 100, interval: float = 40) FuncAnimation
Plot a linkage with an animation.
- Args:
linkage: The linkage to animate. fig: Figure to support the axes. axis: The subplot to draw on. loci: list of list of coordinates. frames: Number of frames to draw the linkage on. interval: Delay between frames in milliseconds.
- Returns:
The animation object.
- pylinkage.visualizer.plot_kinematics_frame(linkage: Linkage, axis: Axes, positions: NDArray[np.float64], velocities: NDArray[np.float64] | None = None, accelerations: NDArray[np.float64] | None = None, *, velocity_scale: float = 0.1, acceleration_scale: float = 0.01, show_velocity: bool = True, show_acceleration: bool = False) None
Plot a single frame of linkage with kinematic vectors.
- Args:
linkage: The linkage being visualized. axis: Matplotlib axes to draw on. positions: Joint positions for this frame, shape (n_joints, 2). velocities: Joint velocities, shape (n_joints, 2). Optional. accelerations: Joint accelerations, shape (n_joints, 2). Optional. velocity_scale: Scaling factor for velocity arrows. acceleration_scale: Scaling factor for acceleration arrows. show_velocity: Whether to show velocity vectors. show_acceleration: Whether to show acceleration vectors.
- pylinkage.visualizer.plot_linkage_dxf(linkage: Linkage, loci: Iterable[tuple[Coord, ...]] | None = None, *, frame_index: int = 0, link_width: float | None = None, joint_radius: float | None = None) ezdxf.drawing.Drawing
Create a DXF drawing of the linkage.
- Args:
linkage: The linkage to export. loci: Optional precomputed loci. If None, runs simulation. frame_index: Which simulation frame to export (0 = first). link_width: Width of link bars in world units. Auto-scaled if None. joint_radius: Radius of joint circles in world units. Auto-scaled if None.
- Returns:
An ezdxf Drawing object ready to save.
- Example:
>>> from pylinkage.visualizer import plot_linkage_dxf, save_linkage_dxf >>> doc = plot_linkage_dxf(linkage) >>> doc.saveas("linkage.dxf")
- pylinkage.visualizer.plot_linkage_plotly(linkage: Linkage, loci: Iterable[tuple[Coord, ...]] | None = None, *, title: str | None = None, show_dimensions: bool = False, show_loci: bool = True, show_labels: bool = True, width: int = 800, height: int = 600) Figure
Create an interactive Plotly diagram of a linkage.
- Args:
linkage: The linkage to visualize. loci: Optional precomputed loci. If None, runs simulation. title: Optional title for the diagram. show_dimensions: Whether to show dimension annotations. show_loci: Whether to show joint movement paths. show_labels: Whether to show joint name labels. width: Figure width in pixels. height: Figure height in pixels.
- Returns:
A plotly Figure object.
- pylinkage.visualizer.plot_linkage_plotly_with_velocity(linkage: Linkage, frame_index: int = 0, *, title: str | None = None, show_loci: bool = True, show_velocity: bool = True, velocity_scale: float | None = None, velocity_color: str = '#2196F3', width: int = 900, height: int = 700) Figure
Create an interactive Plotly diagram with velocity vectors.
Runs simulation with kinematics and displays velocity arrows at the specified frame.
- Args:
linkage: The linkage to visualize. frame_index: Which frame to display (0 = initial position). title: Optional title for the diagram. show_loci: Whether to show joint movement paths. show_velocity: Whether to show velocity vectors. velocity_scale: Scaling factor for arrows. Auto-computed if None. velocity_color: Color for velocity arrows. width: Figure width in pixels. height: Figure height in pixels.
- Returns:
A plotly Figure object.
- Example:
>>> linkage.set_input_velocity(crank, omega=10.0) >>> fig = plot_linkage_plotly_with_velocity(linkage, frame_index=25) >>> fig.show()
- pylinkage.visualizer.plot_linkage_svg(linkage: Linkage, loci: Iterable[tuple[Coord, ...]] | None = None, *, title: str | None = None, show_dimensions: bool = False, show_loci: bool = True, show_labels: bool = True, link_style: Literal['bar', 'bone', 'line'] = 'bar', scale: float = 80, padding: float = 100) Drawing
Create a publication-quality SVG kinematic diagram.
- Args:
linkage: The linkage to visualize. loci: Optional precomputed loci. If None, runs simulation. title: Optional title for the diagram. show_dimensions: Whether to show dimension lines. show_loci: Whether to show joint movement paths. show_labels: Whether to show joint labels. link_style: Visual style for links (‘bar’, ‘bone’, or ‘line’). scale: Pixels per unit. padding: Canvas padding in pixels.
- Returns:
A drawsvg.Drawing object.
- pylinkage.visualizer.plot_linkage_svg_with_velocity(linkage: Linkage, positions: NDArray[np.float64] | Sequence[tuple[float, float]], velocities: NDArray[np.float64] | Sequence[tuple[float, float]], *, title: str | None = None, show_labels: bool = True, link_style: Literal['bar', 'bone', 'line'] = 'bar', velocity_scale: float | None = None, velocity_color: str = '#0066CC', skip_static: bool = True, scale: float = 80, padding: float = 100) Drawing
Create an SVG diagram with velocity vectors overlaid.
- Args:
linkage: The linkage to visualize. positions: Joint positions, shape (n_joints, 2) or list of (x, y). velocities: Joint velocities, shape (n_joints, 2) or list of (vx, vy). title: Optional title for the diagram. show_labels: Whether to show joint labels. link_style: Visual style for links (‘bar’, ‘bone’, or ‘line’). velocity_scale: Scaling factor for velocity arrows. Auto-computed if None. velocity_color: Color for velocity arrows. skip_static: Whether to skip velocity arrows for static joints. scale: Pixels per unit. padding: Canvas padding in pixels.
- Returns:
A drawsvg.Drawing object.
- Example:
>>> linkage.set_input_velocity(crank, omega=10.0) >>> positions, velocities = linkage.step_fast_with_kinematics() >>> drawing = plot_linkage_svg_with_velocity( ... linkage, positions[0], velocities[0] ... ) >>> drawing.save_svg("linkage_with_velocity.svg")
- pylinkage.visualizer.plot_static_linkage(linkage: Linkage, axis: Axes, loci: Iterable[tuple[Coord, ...]], locus_highlights: list[list[Coord]] | None = None, show_legend: bool = False) None
Plot a linkage without movement.
- Args:
linkage: The linkage you want to see. axis: The graph we should draw on. loci: List of list of coordinates. They will be plotted. locus_highlights: If a list, should be a list of list of coordinates you
want to see highlighted.
show_legend: To add an automatic legend to the graph.
- pylinkage.visualizer.plot_velocity_vectors(linkage: Linkage, axis: Axes, positions: NDArray[np.float64] | Sequence[tuple[float, float]], velocities: NDArray[np.float64] | Sequence[tuple[float, float]], *, scale: float = 0.1, color: str = 'blue', width: float = 0.005, label: str = 'Velocity', skip_static: bool = True) Quiver
Plot velocity vectors as arrows at joint positions.
- Args:
linkage: The linkage being visualized. axis: Matplotlib axes to draw on. positions: Joint positions, shape (n_joints, 2) or list of (x, y). velocities: Joint velocities, shape (n_joints, 2) or list of (vx, vy). scale: Scaling factor for arrow length. Smaller = longer arrows. color: Arrow color. width: Arrow shaft width as fraction of plot width. label: Legend label for the arrows. skip_static: Whether to skip drawing arrows for static joints.
- Returns:
The Quiver object for further customization.
- pylinkage.visualizer.save_linkage_dxf(linkage: Linkage, path: str | Path, loci: Iterable[tuple[Coord, ...]] | None = None, **kwargs: object) None
Save linkage to a DXF file.
- Args:
linkage: The linkage to export. path: Output file path (should end in .dxf). loci: Optional precomputed loci. **kwargs: Additional arguments passed to plot_linkage_dxf.
- Example:
>>> from pylinkage.visualizer import save_linkage_dxf >>> save_linkage_dxf(linkage, "output.dxf")
- pylinkage.visualizer.save_linkage_step(linkage: Linkage, path: str | Path, loci: Iterable[tuple[Coord, ...]] | None = None, **kwargs: object) None
Save linkage to a STEP file.
- Args:
linkage: The linkage to export. path: Output file path (should end in .step or .stp). loci: Optional precomputed loci. **kwargs: Additional arguments passed to build_linkage_3d.
- Example:
>>> from pylinkage.visualizer import save_linkage_step >>> save_linkage_step(linkage, "output.step")
- pylinkage.visualizer.save_linkage_svg(linkage: Linkage, path: str, loci: Iterable[tuple[Coord, ...]] | None = None, **kwargs: object) None
Save a linkage diagram to an SVG file.
- Args:
linkage: The linkage to visualize. path: Output file path (should end in .svg). loci: Optional precomputed loci. **kwargs: Additional arguments passed to plot_linkage_svg.
- pylinkage.visualizer.save_linkage_svg_with_velocity(linkage: Linkage, path: str, positions: NDArray[np.float64] | Sequence[tuple[float, float]], velocities: NDArray[np.float64] | Sequence[tuple[float, float]], **kwargs: object) None
Save a linkage diagram with velocity vectors to an SVG file.
- Args:
linkage: The linkage to visualize. path: Output file path (should end in .svg). positions: Joint positions, shape (n_joints, 2) or list of (x, y). velocities: Joint velocities, shape (n_joints, 2) or list of (vx, vy). **kwargs: Additional arguments passed to plot_linkage_svg_with_velocity.
- pylinkage.visualizer.show_kinematics(linkage: Linkage, frame_index: int = 0, *, show_velocity: bool = True, show_acceleration: bool = False, velocity_scale: float | None = None, acceleration_scale: float | None = None, figsize: tuple[float, float] = (10, 8), title: str | None = None) Figure
Display linkage with velocity and/or acceleration vectors.
Runs simulation with kinematics computation and displays the result at a specific frame.
- Args:
linkage: The linkage to visualize. frame_index: Which frame to display (0 = initial position). show_velocity: Whether to show velocity vectors. show_acceleration: Whether to show acceleration vectors. velocity_scale: Arrow scale for velocities. Auto-computed if None. acceleration_scale: Arrow scale for accelerations. Auto-computed if None. figsize: Figure size (width, height) in inches. title: Figure title.
- Returns:
The matplotlib Figure object.
- Example:
>>> linkage.set_input_velocity(crank, omega=10.0) >>> fig = show_kinematics(linkage, frame_index=25, show_velocity=True)
- pylinkage.visualizer.show_linkage(linkage: Linkage, save: bool = False, prev: Sequence[Coord] | None = None, loci: Sequence[tuple[Coord, ...]] | None = None, points: int = 100, iteration_factor: float = 1, title: str | None = None, duration: float = 5, fps: int = 24) FuncAnimation
Display results as an animated drawing.
- Args:
linkage: The Linkage you want to draw. save: To save the animation. prev: Previous coordinates to use for linkage. loci: list of loci. points: Number of points to draw for a crank revolution.
Useless when loci are set.
- iteration_factor: A simple way to subdivide the movement. The real
number of points will be points * iteration_factor.
title: Figure title. Defaults to str(len(ani)). duration: Animation duration (in seconds). fps: Number of frames per second for the output video.
- Returns:
The animation object.
- pylinkage.visualizer.swarm_tiled_repr(linkage: Linkage, swarm: tuple[int, Sequence[tuple[float, np.ndarray, Sequence[Coord]]]], fig: Figure, axes: np.ndarray, dimension_func: Callable[[np.ndarray], Sequence[float]] | None = None, points: int = 12, iteration_factor: float = 1) None
Show all the linkages in a swarm in tiled mode.
- Args:
linkage: The original Linkage that will be MODIFIED. swarm: Tuple of (iteration_number, list_of_agents) where each agent is
(score, dimensions, initial_positions).
fig: Figure to support the axes. axes: The subplot to draw on. points: Number of steps to use for each Linkage. iteration_factor: A simple way to subdivide the movement. The real
number of points will be points * iteration_factor.
- dimension_func: If you want a special formatting of dimensions from
agents before passing them to the linkage.