Visualization

Plotting and visualization tools.

Setup Plots

3D eye tracking setup visualization module.

Provides comprehensive 3D visualization functions for eye tracking setups. Handles coordinate transformations and anatomical structure plotting.

pyetsimul.visualization.setup_plots.plot_setup(ax1, eyes_data, look_at_targets, lights=None, cameras=None, cr_3d_lists=None, ref_bounds=None, calib_points=None, screen=None)[source]

Plot 3D eye tracking setup visualization.

Shows eye anatomy, cameras, lights, and corneal reflections in world coordinates.

Parameters:
  • ax1 (Axes) – 3D matplotlib axis

  • eyes_data (list[dict[str, Any]] | dict[str, Any]) – Eye data dict or list of eye data dicts with transformed eye anatomy data

  • look_at_targets (list[Position3D] | Position3D) – Target point or list of target points for each eye

  • lights (list[Light] | Light | None) – Optional Light object or list of Light objects with positions

  • cameras (list[Camera] | Camera | None) – Optional Camera object or list of Camera objects

  • cr_3d_lists (list[list[Any]] | None) – List of lists of corneal reflection 3D positions for each eye

  • ref_bounds (dict[str, tuple[float, float]] | None) – Optional reference bounds dict with ‘x’, ‘y’, ‘z’ keys

  • calib_points (list[Point2D] | None) – Optional calibration points array to plot as black x markers

  • screen (ScreenGeometry | None) – Optional screen geometry to draw the screen border

Returns:

Lists of eye and camera colors used in the plot.

Return type:

Tuple[List[str], List[str]]

pyetsimul.visualization.setup_plots.transform_surface(x_local, y_local, z_local, trans_matrix)[source]

Transform surface coordinates to world coordinates

Return type:

tuple[Vector3D, Vector3D, Vector3D]

Parameters:
pyetsimul.visualization.setup_plots.plot_axis(ax, center, trans_matrix, axis_idx, label, color, length=3)[source]

Plot a single axis with arrow and label

Return type:

None

Parameters:

Camera View

Camera view visualization module.

Provides functions for visualizing the camera’s view of the eye. Shows pupil detection, corneal reflections, and camera image coordinates.

pyetsimul.visualization.camera_view.plot_camera_view_of_eye(camera_images, cameras, cr_3d_lists=None, ax=None, eye_colors=None, camera_colors=None)[source]

Plot camera views of eyes.

Shows what each camera sees - all eyes visible in that camera’s field of view.

Parameters:
  • camera_images (list[CameraImage] | CameraImage) – CameraImage object or list of CameraImage objects (each contains all eyes seen by that camera)

  • cameras (list[Camera] | Camera) – Camera object or list of Camera objects

  • cr_3d_lists (list[list[Any]] | list[Any] | None) – list of lists of corneal reflection 3D positions for each eye, or single list

  • ax (Axes | None) – Optional matplotlib axis

  • eye_colors (list[str] | None) – Optional list of colors for the eyes.

  • camera_colors (list[str] | None) – Optional list of colors for the cameras.

Return type:

None

Interactive

Interactive plotting functions for dynamic visualizations.

Provides interactive eye tracking visualization with keyboard controls for real-time exploration. Enables dynamic visualization of eye tracking with target and eye movement controls.

pyetsimul.visualization.interactive.plot_interactive_setup(eye_base, lights, camera, target_point)[source]

Create and run interactive setup and camera view with keyboard controls.

Parameters:
  • eye_base (Eye) – Base eye object

  • lights (list[Light]) – List of light objects

  • camera (Camera) – Camera object

  • target_point (Position3D) – Initial target point

Return type:

None

pyetsimul.visualization.interactive.plot_interactive_cameras(cameras, eye, target_point)[source]

Create and run interactive camera comparison with keyboard controls.

Parameters:
  • cameras (list[Camera]) – List of Camera objects

  • eye (Eye) – Eye object

  • target_point (Position3D) – Initial target point

Return type:

None

pyetsimul.visualization.interactive.plot_interactive_pupil_comparison(eye_elliptical, eye_realistic, camera, target_point)[source]

Create and run interactive pupil comparison with keyboard controls.

Parameters:
  • eye_elliptical (Eye) – Elliptical pupil eye object

  • eye_realistic (Eye) – Realistic pupil eye object

  • camera (Camera) – Camera object

  • target_point (Position3D) – Initial target point

Return type:

None

Interactive Gaze Plot

Interactive gaze plot for exploring calibration accuracy.

This module provides a standalone interactive plot that visualizes gaze estimation accuracy at calibration points with a 3D setup view. It computes all calibration errors internally from predict functions — no pre-computed arrays needed.

Supports multiple eyes: each eye gets its own predict function, color-coded arrows and predictions on the 2D panel, and all eyes appear in the 3D setup view.

pyetsimul.visualization.interactive_gaze_plot.compute_calibration_errors(predict_fn, eye, calibration_points, plane_info)[source]

Compute calibration errors by predicting at each calibration point.

Returns a dict with arrays needed for the 2D error plot.

Return type:

dict

Parameters:
pyetsimul.visualization.interactive_gaze_plot.render_calibration_view(ax_3d, ax_2d, target_point, eyes, predict_fns, calibration_points, plane_info, cameras, lights, *, cached_calib_data=None, eye_labels=None, eye_colors=None, target_color=None, screen=None, use_legacy_look_at=False, ref_bounds_3d=None, xlim_2d=None, ylim_2d=None)[source]

Render the 3D setup + 2D calibration accuracy view for a given target.

Both axes are cleared and re-plotted. Designed to be called per-frame from an animation, and also used as the rendering primitive of create_interactive_gaze_plot. Eye orientation is handled internally via prepare_eye_data_for_plots / predict_fns; the caller passes the eye objects but does not need to call eye.look_at explicitly.

Parameters:
  • ax_3d (Axes) – 3D matplotlib axes (projection=’3d’).

  • ax_2d (Axes) – 2D matplotlib axes.

  • target_point (Point3D) – Current gaze target.

  • eyes (list[Eye]) – List of Eye objects.

  • predict_fns (list[Callable[[Eye, Point3D], GazePrediction | None]]) – One predict function per eye, (eye, target) -> GazePrediction.

  • calibration_points (list[Point3D]) – 3D calibration target positions.

  • plane_info (PlaneInfo) – Plane detection info for coordinate mapping.

  • cameras (list) – List of cameras.

  • lights (list) – List of lights.

  • cached_calib_data (list[dict] | None) – Optional pre-computed per-eye calibration data (from compute_calibration_errors). Skips recomputation when provided.

  • eye_labels (list[str] | None) – Optional per-eye labels (defaults to “Eye 1”, “Eye 2”, …).

  • eye_colors (list[str] | None) – Optional per-eye colors (defaults to plot config palette).

  • target_color (str | None) – Optional target marker color (defaults to plot config).

  • screen (ScreenGeometry | None) – Optional ScreenGeometry to draw screen border on the 3D plot.

  • use_legacy_look_at (bool) – Whether to use legacy look-at behavior.

  • ref_bounds_3d (dict | None) – Optional fixed 3D axis bounds, passed through to plot_setup.

  • xlim_2d (tuple[float, float] | None) – Optional fixed x-limits for the 2D axes.

  • ylim_2d (tuple[float, float] | None) – Optional fixed y-limits for the 2D axes.

Return type:

dict

Returns:

Dict with ‘errors_mm’ and ‘errors_deg’ lists, one entry per eye that produced a valid prediction at target_point.

pyetsimul.visualization.interactive_gaze_plot.create_interactive_gaze_plot(eyes, predict_fns, calibration_points, plane_info, cameras, lights, use_legacy_look_at=False, eye_labels=None, eye_colors=None, screen=None, show=True)[source]

Create interactive gaze plot with keyboard controls.

Computes calibration errors internally by calling each predict_fn at each calibration point. Provides real-time exploration of gaze tracking accuracy with a 3D setup visualization alongside a 2D error vector plot.

Supports multiple eyes: each eye/predict_fn pair is color-coded on the plot.

Parameters:
  • eyes (list[Eye]) – List of Eye objects to use for gaze prediction.

  • predict_fns (list[Callable[[Eye, Point3D], GazePrediction | None]]) – List of functions that predict gaze given (eye, target_point).

  • calibration_points (list[Point3D]) – List of 3D calibration target positions.

  • plane_info (PlaneInfo) – Plane detection info for coordinate mapping.

  • cameras (list) – List of Camera objects in the setup.

  • lights (list) – List of Light objects in the setup.

  • use_legacy_look_at (bool) – Whether to use legacy look-at behavior.

  • eye_labels (list[str] | None) – Optional labels for each eye (e.g. [“Right”, “Left”]). Defaults to “Eye 1”, “Eye 2”, etc.

  • eye_colors (list[str] | None) – Optional colors for each eye (e.g. [“blue”, “green”]). Defaults to the config eye color palette.

  • screen (ScreenGeometry | None) – Optional ScreenGeometry to draw screen border on the 3D plot.

  • show (bool) – If True (default), print controls and display with plt.show(). If False, close the figure from matplotlib’s manager and return it for saving with fig.savefig().

Return type:

Figure

Returns:

The matplotlib Figure.

Interactive Controls

Centralized keyboard controls for interactive plots.

class pyetsimul.visualization.interactive_controls.InteractiveControls(eyes, target_point, step_size=2.5, initial_eye_positions=None, initial_target_position=None, custom_handlers=None)[source]

Bases: object

Centralized keyboard controls for interactive eye tracking plots.

Parameters:
__init__(eyes, target_point, step_size=2.5, initial_eye_positions=None, initial_target_position=None, custom_handlers=None)[source]

Initialize interactive controls.

Parameters:
  • eyes (list[Eye]) – List of Eye objects to control (IJKL moves all together).

  • target_point (Point3D) – Target point for gaze.

  • step_size (float) – Movement step size in mm.

  • initial_eye_positions (list[Position3D] | None) – Initial positions for each eye (defaults to current).

  • initial_target_position (Point3D | None) – Initial target position (defaults to current).

  • custom_handlers (dict[str, Callable] | None) – Additional key handlers.

Return type:

None

set_update_callback(callback)[source]

Set callback function to call after position changes.

Return type:

None

Parameters:

callback (Callable)

handle_key_press(event)[source]

Handle keyboard input and return True if key was handled.

Return type:

bool

Parameters:

event (KeyEvent)

reset_positions()[source]

Reset all eyes and target to initial positions.

Return type:

None

static print_controls(include_reset=True, additional_controls=None)[source]

Print standardized control instructions.

Return type:

None

Parameters:

Eye Anatomy

Eye anatomy visualization using structured types and vector arithmetic.

Provides 3D visualization functions for eye anatomy using structured types. Supports anatomical accuracy and vector-based transformations.

pyetsimul.visualization.eye_anatomy.plot_eye_anatomy(eye, ax=None)[source]

Plot 3D eye anatomy using structured types and vector arithmetic.

Visualizes anatomical structures of the eye in 3D using vector-based transformations. Useful for understanding eye geometry and verifying anatomical accuracy. Assumes the eye is already oriented as desired.

Parameters:
  • eye (Eye) – Eye object to plot (required) - should already be oriented as desired

  • ax (Axes | None) – Matplotlib 3D axis (optional, creates new if None)

Raises:

ValueError – If eye has no current target point (call eye.look_at() first)

Return type:

Axes

Integrated Plots

Integrated plotting functions for complete visualizations.

Provides high-level functions that combine 3D setup and camera views for comprehensive eye tracking visualization.

pyetsimul.visualization.integrated_plots.plot_setup_and_camera_view(eyes, look_at_targets, cameras=None, lights=None, calib_points=None, ax1=None, ax2=None, fig=None, ref_bounds=None)[source]

Create comprehensive eye tracking visualization with 3D setup and camera view.

Shows 3D scene and camera image for complete system visualization.

Parameters:
Returns:

Matplotlib figure object

Return type:

fig

Gaze Accuracy Plots

Gaze accuracy visualization utilities.

Provides specialized plotting functionality for gaze accuracy analysis results.

pyetsimul.visualization.gaze_accuracy_plots.detect_variation_plane(variation)[source]

Detect which 2D plane a parameter variation occurs in.

Analyzes variation ranges to determine which two axes actually vary.

Parameters:

variation (ParameterVariation) – Parameter variation object with dx, dy, dz attributes

Returns:

(primary_axis, secondary_axis, primary_range, secondary_range)

where axes are ‘x’, ‘y’, ‘z’ and ranges are [min, max]

Return type:

tuple

pyetsimul.visualization.gaze_accuracy_plots.extract_variation_coords(position, primary_axis, secondary_axis)[source]

Extract 2D coordinates from 3D position based on variation axes.

Return type:

tuple[float, float]

Parameters:
class pyetsimul.visualization.gaze_accuracy_plots.GazeAccuracyPlotter[source]

Bases: object

Handles plotting for gaze accuracy analysis results.

plot(gaze_result, eye_tracker, title_prefix='Gaze Accuracy Analysis', plot_mode='auto', show=True, ax=None)[source]

Plot gaze accuracy results with flexible 2D/3D visualization.

Parameters:
  • gaze_result (GazeAccuracyResult) – GazeAccuracyResult instance with analysis data

  • eye_tracker (EyeTracker) – Eye tracker instance (used to access plane_info for 2D plotting)

  • title_prefix (str) – Title prefix for the plot

  • plot_mode (str) – “2d”, “3d”, or “auto” (auto chooses 2D for 2D trackers, 3D otherwise)

  • show (bool) – If True (default), display the figure with plt.show() (blocks until closed). If False, return the figure for saving (fig.savefig()) without displaying. The figure is removed from matplotlib’s manager to prevent it from appearing unexpectedly in later plt.show() calls.

  • ax (Axes | None) – Optional matplotlib Axes to draw on. If provided, show is ignored and the caller manages the figure lifecycle.

Return type:

Figure

Returns:

The matplotlib Figure.

Analysis Plots

Analysis visualization utilities.

This module provides plotting functions for gaze tracking analysis results.

pyetsimul.visualization.analysis_plots.plot_error_vectors_2d(X, Y, U, V, errors, title_prefix='', width=0.002, max_arrow_ratio=0.3, mark_target_positions=False, mark_predicted_positions=False, show_grid=True, auto_adjust_limits=True, figure_size=(10, 8), xlabel='Observer X position (mm)', ylabel='Observer Y position (mm)', ax=None)[source]

Plot gaze tracking error vectors with adaptive scaling.

Creates quiver plot showing error vectors at measurement points.

Parameters:
  • X (ndarray) – Grid coordinates for vector X positions

  • Y (ndarray) – Grid coordinates for vector Y positions

  • U (ndarray) – Error components in X direction

  • V (ndarray) – Error components in Y direction

  • errors (dict[str, dict[str, float]]) – dictionary with error statistics (from calculate_error_statistics)

  • title_prefix (str) – Prefix text for plot title

  • width (float) – Arrow width

  • max_arrow_ratio (float) – Maximum arrow length as fraction of plot range

  • mark_target_positions (bool) – Show blue crosses at target positions

  • mark_predicted_positions (bool) – Show red dots at predicted positions

  • show_grid (bool) – Show grid lines

  • auto_adjust_limits (bool) – Automatically adjust plot limits

  • figure_size (tuple[int, int]) – Figure size tuple

  • xlabel (str) – X-axis label

  • ylabel (str) – Y-axis label

  • ax (Axes | None) – Optional matplotlib Axes to draw on. If None, a new figure is created.

Return type:

Figure

Returns:

The matplotlib Figure.

pyetsimul.visualization.analysis_plots.plot_error_vectors_3d(positions, error_vectors, angular_errors, errors, title_prefix='', max_arrow_ratio=0.2, show_grid=True, figure_size=(12, 10), position_labels=('X position', 'Y position', 'Z position'), ax=None)[source]

Plot 3D gaze tracking error vectors with adaptive scaling.

Creates 3D quiver plot showing error vectors in 3D space.

Parameters:
  • positions (ndarray) – Array of shape (N, 3) with [x, y, z] positions

  • error_vectors (ndarray) – Array of shape (N, 3) with [dx, dy, dz] error vectors

  • angular_errors (ndarray) – Array of shape (N,) with angular errors in degrees

  • errors (dict[str, dict[str, float]]) – dictionary with error statistics (from calculate_error_statistics)

  • title_prefix (str) – Prefix text for plot title

  • max_arrow_ratio (float) – Maximum arrow length as fraction of plot range

  • show_grid (bool) – Show grid lines

  • figure_size (tuple[int, int]) – Figure size tuple

  • position_labels (tuple[str, str, str]) – Labels for X, Y, Z axes

  • ax (Axes | None) – Optional 3D matplotlib Axes to draw on. If None, a new figure is created.

Return type:

Figure

Returns:

The matplotlib Figure.

Plot Config

Centralized plot styling configuration for PyEtSimul visualization system.

This module provides structured configuration classes for consistent styling across all visualization components. It defines element-specific styling that preserves functional visual distinctions while eliminating code duplication.

class pyetsimul.visualization.plot_config.ColorPalettes(eyes=None, eyes_light=None, cameras=None, lights=None, eye_globe='lightgray', cornea_outer='steelblue', cornea_inner='darkturquoise', pupil='black', fovea='orange', eyelid='#836641', target='red', corneal_reflection='gold', rotation_center='navy', calibration_points='black', optical_axis='green', visual_axis='red', camera_comparison=None)[source]

Bases: object

Color definitions organized by element type for consistent visual coding.

Parameters:
  • eyes (list[str] | None)

  • eyes_light (list[str] | None)

  • cameras (list[str] | None)

  • lights (list[str] | None)

  • eye_globe (str)

  • cornea_outer (str)

  • cornea_inner (str)

  • pupil (str)

  • fovea (str)

  • eyelid (str)

  • target (str)

  • corneal_reflection (str)

  • rotation_center (str)

  • calibration_points (str)

  • optical_axis (str)

  • visual_axis (str)

  • camera_comparison (list[str] | None)

eyes: list[str] | None = None
eyes_light: list[str] | None = None
cameras: list[str] | None = None
lights: list[str] | None = None
eye_globe: str = 'lightgray'
cornea_outer: str = 'steelblue'
cornea_inner: str = 'darkturquoise'
pupil: str = 'black'
fovea: str = 'orange'
eyelid: str = '#836641'
target: str = 'red'
corneal_reflection: str = 'gold'
rotation_center: str = 'navy'
calibration_points: str = 'black'
optical_axis: str = 'green'
visual_axis: str = 'red'
camera_comparison: list[str] | None = None
class pyetsimul.visualization.plot_config.MarkerConfig(scene_elements=200, key_landmarks=80, landmarks=15, corneal_reflections=10, calibration_points=40, small_details=25, surface_points=3, cornea_surface_anterior=1, cornea_surface_posterior=1, cornea_center_outer=30, cornea_center_inner=20, camera_comparison=None)[source]

Bases: object

Marker styling organized by visual importance hierarchy.

Parameters:
  • scene_elements (int)

  • key_landmarks (int)

  • landmarks (int)

  • corneal_reflections (int)

  • calibration_points (int)

  • small_details (int)

  • surface_points (int)

  • cornea_surface_anterior (int)

  • cornea_surface_posterior (int)

  • cornea_center_outer (int)

  • cornea_center_inner (int)

  • camera_comparison (list[str] | None)

scene_elements: int = 200
key_landmarks: int = 80
landmarks: int = 15
corneal_reflections: int = 10
calibration_points: int = 40
small_details: int = 25
surface_points: int = 3
cornea_surface_anterior: int = 1
cornea_surface_posterior: int = 1
cornea_center_outer: int = 30
cornea_center_inner: int = 20
camera_comparison: list[str] | None = None
class pyetsimul.visualization.plot_config.LineConfig(thick_lines=2.0, standard_lines=1.0, thin_lines=0.1, solid='-', dashed='--', primary_alpha=0.9, secondary_alpha=0.7, background_alpha=0.5, grid_alpha=0.3)[source]

Bases: object

Line styling organized by semantic purpose.

Parameters:
thick_lines: float = 2.0
standard_lines: float = 1.0
thin_lines: float = 0.1
solid: str = '-'
dashed: str = '--'
primary_alpha: float = 0.9
secondary_alpha: float = 0.7
background_alpha: float = 0.5
grid_alpha: float = 0.3
class pyetsimul.visualization.plot_config.FontConfig(title=14, subtitle=12, legend=10, annotation=8, bold_weight='bold')[source]

Bases: object

Font sizing with clear hierarchical structure.

Parameters:
  • title (int)

  • subtitle (int)

  • legend (int)

  • annotation (int)

  • bold_weight (str)

title: int = 14
subtitle: int = 12
legend: int = 10
annotation: int = 8
bold_weight: str = 'bold'
class pyetsimul.visualization.plot_config.LayoutConfig(single_plot=(10, 8), wide_comparison=(16, 8), extra_wide=(18, 8), integrated_view=(20, 8), anatomy_detail=(14, 10), legend_outside_right=None, legend_upper_left=None)[source]

Bases: object

Layout parameters for consistent plot structure.

Parameters:
single_plot: tuple[int, int] = (10, 8)
wide_comparison: tuple[int, int] = (16, 8)
extra_wide: tuple[int, int] = (18, 8)
integrated_view: tuple[int, int] = (20, 8)
anatomy_detail: tuple[int, int] = (14, 10)
legend_outside_right: dict[str, str | tuple[float, float]] | None = None
legend_upper_left: dict[str, str] | None = None
class pyetsimul.visualization.plot_config.ElementConfig(grid_enabled=True, equal_aspect=True, camera_border_width=2.0, camera_border_alpha=0.8, pupil_boundary_width=1.0, pupil_boundary_alpha=0.9, corneal_reflection_width=1.5, eyelid_width=2.0)[source]

Bases: object

Specific styling for individual plot elements.

Parameters:
  • grid_enabled (bool)

  • equal_aspect (bool)

  • camera_border_width (float)

  • camera_border_alpha (float)

  • pupil_boundary_width (float)

  • pupil_boundary_alpha (float)

  • corneal_reflection_width (float)

  • eyelid_width (float)

grid_enabled: bool = True
equal_aspect: bool = True
camera_border_width: float = 2.0
camera_border_alpha: float = 0.8
pupil_boundary_width: float = 1.0
pupil_boundary_alpha: float = 0.9
corneal_reflection_width: float = 1.5
eyelid_width: float = 2.0
class pyetsimul.visualization.plot_config.PlotConfig(colors, markers, lines, fonts, layout, elements)[source]

Bases: object

Complete plot styling configuration combining all component configurations.

Parameters:
colors: ColorPalettes
markers: MarkerConfig
lines: LineConfig
fonts: FontConfig
layout: LayoutConfig
elements: ElementConfig
pyetsimul.visualization.plot_config.create_plot_config()[source]

Factory function to create default plot configuration.

Returns:

Complete styling configuration with PyEtSimul defaults

Return type:

PlotConfig

Coordinate Utilities

Data preparation utilities for visualization.

Provides coordinate transformations and data preparation for eye tracking visualization. Handles eye anatomy, camera imaging, and corneal reflection calculations. Support for multiple eyes, cameras, and lights.

pyetsimul.visualization.coordinate_utils.prepare_eye_data_for_plots(eyes, look_at_targets, lights=None, cameras=None, use_legacy_lookat=False)[source]

Prepare eye visualization data for plotting.

Transforms eye anatomies to world coordinates and generates camera images. Calculates corneal reflections and optical axes for 3D visualization.

Parameters:
  • eyes (list[Eye] | Eye) – Eye object or list of Eye objects

  • look_at_targets (list[Position3D] | Position3D) – Target point or list of target points, one per eye

  • lights (list[Light] | Light | None) – Optional Light object or list of Light objects with positions

  • cameras (list[Camera] | Camera | None) – Optional Camera object or list of Camera objects

  • use_legacy_lookat (bool) – Whether to use the legacy look-at method

Returns:

Contains eyes_data list, camera_images list, and cr_3d_lists for plotting

Return type:

dict

Transforms

Coordinate transformation utilities for visualization.

Provides functions for transforming local surface coordinates to world coordinates for 3D plotting.

pyetsimul.visualization.transforms.transform_surface(x_local, y_local, z_local, trans_matrix)[source]

Transform surface coordinates to world coordinates for 3D visualization.

Applies homogeneous transformation to local surface coordinates for plotting.

Parameters:
  • x_local (ndarray) – Local surface X coordinates

  • y_local (ndarray) – Local surface Y coordinates

  • z_local (ndarray) – Local surface Z coordinates

  • trans_matrix (TransformationMatrix) – 4x4 transformation matrix

Return type:

tuple[ndarray, ndarray, ndarray]

Returns:

Tuple of transformed (x, y, z) world coordinates