Source code for fastplotlib.graphics.utils

from contextlib import contextmanager
from typing import Callable, Iterable, Sequence

import numpy as np

from ._collection_base import GraphicCollection
from ._base import Graphic


[docs] @contextmanager def pause_events(*graphics: Graphic, event_handlers: Iterable[Callable] = None): """ Context manager for pausing Graphic events. Optionally pass in only specific event handlers which are blocked. Other events for the graphic will not be blocked. Examples -------- .. code-block:: # pass in any number of graphics with fpl.pause_events(graphic1, graphic2, graphic3): # enter context manager # all events are blocked from graphic1, graphic2, graphic3 # context manager exited, event states restored. """ if not all([isinstance(g, Graphic) for g in graphics]): raise TypeError( f"`pause_events` only takes Graphic instances as arguments, " f"you have passed the following types:\n{[type(g) for g in graphics]}" ) original_vals = [g.block_events for g in graphics] for g in graphics: if event_handlers is not None: g.block_handlers.extend([e for e in event_handlers]) else: g.block_events = True yield for g, value in zip(graphics, original_vals): if event_handlers is not None: g.block_handlers.clear() else: g.block_events = value
def get_nearest_graphics_indices( pos: tuple[float, float] | tuple[float, float, float], graphics: Sequence[Graphic] | GraphicCollection, ) -> np.ndarray[int]: """ Returns indices of the nearest ``graphics`` to the passed position ``pos`` in world space in order of closest to furtherst. Uses the distance between ``pos`` and the center of the bounding sphere for each graphic. Parameters ---------- pos: tuple[float, float] | tuple[float, float, float] (x, y) or (x, y, z) position in world space, the z-axis is ignored when calculating L2 norms if ``pos`` is 2D graphics: Sequence, i.e. array, list, tuple, etc. of Graphic | GraphicCollection the graphics from which to return a sorted array of graphics in order of closest to furthest graphic Returns ------- ndarray[int] indices of the nearest nearest graphics to ``pos`` in order """ if isinstance(graphics, GraphicCollection): graphics = graphics.graphics if not all(isinstance(g, Graphic) for g in graphics): raise TypeError("all elements of `graphics` must be Graphic objects") pos = np.asarray(pos).ravel() if pos.shape != (2,) and pos.shape != (3,): raise TypeError( f"pos.shape must be (2,) or (3,), the shape of pos you have passed is: {pos.shape}" ) # get centers centers = np.empty(shape=(len(graphics), len(pos))) for i in range(centers.shape[0]): centers[i] = graphics[i].world_object.get_world_bounding_sphere()[: len(pos)] # l2 distances = np.linalg.norm(centers[:, : len(pos)] - pos, ord=2, axis=1) sort_indices = np.argsort(distances) return sort_indices def get_nearest_graphics( pos: tuple[float, float] | tuple[float, float, float], graphics: Sequence[Graphic] | GraphicCollection, ) -> np.ndarray[Graphic]: """ Returns the nearest ``graphics`` to the passed position ``pos`` in world space. Uses the distance between ``pos`` and the center of the bounding sphere for each graphic. Parameters ---------- pos: tuple[float, float] | tuple[float, float, float] (x, y) or (x, y, z) position in world space, the z-axis is ignored when calculating L2 norms if ``pos`` is 2D graphics: Sequence, i.e. array, list, tuple, etc. of Graphic | GraphicCollection the graphics from which to return a sorted array of graphics in order of closest to furthest graphic Returns ------- ndarray[Graphic] nearest graphics to ``pos`` in order """ if isinstance(graphics, GraphicCollection): graphics = graphics.graphics sort_indices = get_nearest_graphics_indices(pos, graphics) return np.asarray(graphics)[sort_indices]