larvaworld.lib.plot.util ======================== .. py:module:: larvaworld.lib.plot.util .. autoapi-nested-parse:: Methods used in plotting Functions --------- .. autoapisummary:: larvaworld.lib.plot.util.plot_quantiles larvaworld.lib.plot.util.plot_mean_and_range larvaworld.lib.plot.util.circular_hist larvaworld.lib.plot.util.circNarrow larvaworld.lib.plot.util.confidence_ellipse larvaworld.lib.plot.util.dataset_legend larvaworld.lib.plot.util.label_diff larvaworld.lib.plot.util.annotate_plot larvaworld.lib.plot.util.dual_half_circle larvaworld.lib.plot.util.save_plot larvaworld.lib.plot.util.process_plot larvaworld.lib.plot.util.prob_hist larvaworld.lib.plot.util.single_boxplot larvaworld.lib.plot.util.configure_subplot_grid larvaworld.lib.plot.util.define_end_ks larvaworld.lib.plot.util.get_vs larvaworld.lib.plot.util.color_epochs Module Contents --------------- .. py:function:: plot_quantiles(df: numpy.ndarray | pd.DataFrame | pd.Series, x: Optional[numpy.ndarray] = None, **kwargs: Any) -> None Plot quantiles or confidence intervals along with the mean. Computes and plots 25th, 50th (median), and 75th percentiles with shaded interquartile range. Handles numpy arrays, DataFrames, or Series. Args: df: Data to compute quantiles from. If numpy.ndarray, quantiles are computed along the first axis (columns). If pandas.DataFrame or pandas.Series, quantiles are computed grouped by the 'Step' level x: X-axis values for the plot. Uses default range if None **kwargs: Additional keyword arguments passed to plot_mean_and_range Raises: Exception: If the input data type is not recognized Example: >>> plot_quantiles(data_array, x_values, axis=plt.gca(), color='blue', label='Data') .. py:function:: plot_mean_and_range(x: numpy.ndarray, mean: numpy.ndarray | pd.Series, lb: numpy.ndarray | pd.Series, ub: numpy.ndarray | pd.Series, axis: matplotlib.axes.Axes, color: str, color_mean: Optional[str] = None, label: Optional[str] = None, linestyle: str = 'solid', linewidth: int = 2) -> None Plot the mean and a shaded range (quantiles or confidence intervals). Draws mean line with shaded region between lower and upper bounds, commonly used for showing uncertainty or variability. Args: x: X-axis values for the plot mean: Mean values to be plotted lb: Lower bound of the range ub: Upper bound of the range axis: Matplotlib axes where the plot will be drawn color: Color of the shaded range color_mean: Color of the mean line. Uses color if None label: Label for the legend. Defaults to None linestyle: Line style for the mean line ('solid', 'dashed'). Defaults to 'solid' linewidth: Line width for the mean line. Defaults to 2 Example: >>> plot_mean_and_range(x_values, mean_values, lower_bound, upper_bound, plt.gca(), color='blue', label='Mean and Range') .. py:function:: circular_hist(ax: matplotlib.axes.Axes, x: numpy.ndarray, bins: int = 16, density: bool = True, offset: float = 0, gaps: bool = True, **kwargs: Any) -> Tuple[numpy.ndarray, numpy.ndarray, Any] Produce a circular histogram of angles on polar axes. Creates polar histogram showing angular distribution with optional density normalization and customizable bin partitioning. Args: ax: Polar axes instance created with subplot_kw=dict(projection='polar') x: Angles to plot in radians bins: Number of equal-width bins. Defaults to 16 density: If True, plot frequency proportional to area. If False, plot frequency proportional to radius. Defaults to True offset: Offset for the location of 0 direction in radians. Defaults to 0 gaps: Whether to allow gaps between bins. When False, bins partition entire [-pi, pi] range. Defaults to True **kwargs: Additional keyword arguments passed to matplotlib bar plot Returns: Tuple of (n, bins, patches) where n is number of values in each bin, bins are bin edges, and patches is BarContainer or list of Polygon Example: >>> n, bins, patches = circular_hist(polar_ax, angle_data, bins=20, density=True) .. py:function:: circNarrow(ax: matplotlib.axes.Axes, data: numpy.ndarray, alpha: float, label: str, color: str, Nbins: int = 16) -> None Create a circular histogram with an arrow indicator. Combines polar histogram with fancy arrow pointing to mean direction, useful for visualizing angular distributions with directional bias. Args: ax: Polar axes instance created with subplot_kw=dict(projection='polar') data: Angles to plot in radians alpha: Transparency of the circular histogram and arrow label: Label for the circular histogram color: Color of the circular histogram and arrow Nbins: Number of equal-width bins. Defaults to 16 Example: >>> circNarrow(polar_ax, angle_data, alpha=0.5, label='Orientation', color='blue', Nbins=16) .. py:function:: confidence_ellipse(x: numpy.ndarray, y: numpy.ndarray, ax: matplotlib.axes.Axes, n_std: float = 3.0, facecolor: str = 'none', **kwargs: Any) -> Any Create a plot of the covariance confidence ellipse of *x* and *y*. Parameters ---------- x, y : array-like, shape (n, ) Input data. ax : matplotlib.axes.Axes The axes object_class to draw the ellipse into. n_std : float The number of standard deviations to determine the ellipse'sigma radiuses. **kwargs Forwarded to `~matplotlib.patches.Ellipse` Returns ------- matplotlib.patches.Ellipse .. py:function:: dataset_legend(labels: Sequence[str], colors: Sequence[str], ax: Optional[matplotlib.axes.Axes] = None, anchor: Optional[Tuple[float, float]] = None, handlelength: float = 0.5, handleheight: float = 0.5, **kwargs: Any) -> Any Create a legend for all datasets with their specified labels and colors. Generates custom legend with colored patch handles for multiple datasets, with customizable positioning and handle dimensions. Args: labels: List of labels for each dataset colors: List of colors corresponding to each dataset ax: Axes to which legend should be added. Uses current axes if None anchor: Bounding box anchor coordinates for legend. Defaults to None handlelength: Length of legend handles. Defaults to 0.5 handleheight: Height of legend handles. Defaults to 0.5 **kwargs: Additional keyword arguments passed to legend Returns: matplotlib.legend.Legend: The created legend Example: >>> leg = dataset_legend(['Control', 'Test'], ['blue', 'red'], ax=axes, anchor=(1.05, 1)) .. py:function:: label_diff(i: int, j: int, text: str, X: Sequence[float], Y: Sequence[float], ax: matplotlib.axes.Axes) -> None Label the difference between two data points with an annotation and an arrow. Draws horizontal bracket with text annotation between two points, commonly used for showing statistical significance. Args: i: Index of the first data point j: Index of the second data point text: Text label for the difference annotation X: List of x-coordinates for data points Y: List of y-coordinates for data points ax: Matplotlib axes on which to annotate the difference Example: >>> label_diff(0, 1, '***', [1, 2], [10, 12], ax) .. py:function:: annotate_plot(box: Any, data: pandas.DataFrame, x: str, y: str, hue: Optional[str] = None, show_ns: bool = True, target_only: Any = None, **kwargs: Any) -> None Annotate a plot with Mann-Whitney U test p-values. Performs pairwise Mann-Whitney U tests and adds statistical annotations (stars) to boxplots or similar plots using statannot. Args: box: Seaborn plot object to annotate data: DataFrame containing the data x: Column name for the x-axis variable y: Column name for the y-axis variable hue: Column name for grouping data by hue. Defaults to None show_ns: Whether to display annotations for non-significant comparisons. Defaults to True target_only: Specify a target value for comparisons. Defaults to None **kwargs: Additional arguments for annotation customization Example: >>> annotate_plot(box, data, x='group', y='value', show_ns=False, target_only='control') .. py:function:: dual_half_circle(center: Tuple[float, float], radius: float = 0.04, angle: float = 90, ax: Optional[matplotlib.axes.Axes] = None, colors: Tuple[str, str] = ('W', 'k'), **kwargs: Any) -> List[Any] Add two half circles to axes with specified face colors rotated at angle. Creates two wedge patches forming complete circle with different colored halves, rotated to specified angle in degrees. Args: center: Center coordinates of the half circles radius: Radius of the half circles. Defaults to 0.04 angle: Angle by which the half circles are rotated in degrees. Defaults to 90 ax: Matplotlib axes to add half circles to. Uses current axes if None colors: Face colors of the two half circles (left half, right half). Defaults to ('W', 'k') **kwargs: Additional keyword arguments to customize the appearance of the half circles Returns: List containing the two half circle wedge patches Example: >>> wedges = dual_half_circle((0.5, 0.5), radius=0.05, angle=45, colors=('red', 'blue')) .. py:function:: save_plot(fig: matplotlib.figure.Figure, filepath: str, filename: str) -> None Save a Matplotlib figure to a specified file path. Saves figure at high resolution (300 DPI), closes it, and prints confirmation message. Args: fig: Matplotlib figure to save filepath: Full file path where the figure should be saved filename: Name of the file to save Example: >>> save_plot(fig, '/path/to/output.png', 'output.png') .. py:function:: process_plot(fig: matplotlib.figure.Figure, save_to: Optional[str], filename: str, return_fig: bool = False, show: bool = False) -> Any Process and optionally save or show a Matplotlib figure. Handles common plot finalization: showing, saving to file, and returning figure or metadata based on return_fig flag. Args: fig: Matplotlib figure to process save_to: Directory where the figure should be saved. Figure won't be saved if None filename: Name of the file to save return_fig: Whether to return the figure in the result. Defaults to False show: Whether to display the figure. Defaults to False Returns: If return_fig=False: The processed figure If return_fig=True: Tuple of (fig, save_to, filename) Example: >>> result = process_plot(fig, save_to='./plots', filename='output.png', return_fig=True, show=False) .. py:function:: prob_hist(vs: Sequence[numpy.ndarray], colors: Sequence[str], labels: Sequence[str], bins: int | Sequence[float], ax: matplotlib.axes.Axes, hist_type: str = 'sns.hist', kde: bool = False, sns_kws: Dict[str, Any] = {}, plot_fit: bool = True, **kwargs: Any) -> None Create a probability histogram or distribution plot for multiple datasets. Generates probability histograms using seaborn or matplotlib with optional KDE overlay and polynomial fit smoothing. Args: vs: List of arrays - datasets to plot colors: List of colors for each dataset labels: List of labels for the legend bins: Number of bins or bin edges for the histogram ax: Matplotlib axis object to plot on hist_type: Type of histogram to create ('plt.hist' or 'sns.hist'). Defaults to 'sns.hist' kde: Whether to overlay a kernel density estimate. Defaults to False sns_kws: Additional keyword arguments for Seaborn. Defaults to {} plot_fit: Whether to plot a smoothed fit curve. Defaults to True **kwargs: Additional keyword arguments for the histogram Example: >>> fig, ax = plt.subplots() >>> prob_hist([data1, data2], ['blue', 'green'], ['Dataset 1', 'Dataset 2'], bins=20, ax=ax) >>> plt.show() .. py:function:: single_boxplot(x: str, y: str, ax: matplotlib.axes.Axes, data: pandas.DataFrame, hue: Optional[str] = None, palette: Any = None, color: Optional[str] = None, annotation: bool = True, show_ns: bool = False, target_only: Optional[str] = None, stripplot: bool = True, **kwargs: Any) -> None Create a single boxplot with optional annotations and stripplot. Generates seaborn boxplot with optional statistical annotations and overlaid stripplot showing individual data points. Args: x: Column name for the x-axis y: Column name for the y-axis ax: Matplotlib axes where the boxplot will be drawn data: DataFrame - the data source hue: Grouping variable that will produce boxes with different colors. Defaults to None palette: Color palette to use for coloring the boxes. Defaults to None color: Color for the boxes. Defaults to None annotation: Whether to annotate the plot with statistical information. Defaults to True show_ns: Show non-significant comparisons. Defaults to False target_only: Filter the data to include only a specific target. Defaults to None stripplot: Whether to include a stripplot alongside the boxplot. Defaults to True **kwargs: Additional keyword arguments to customize the boxplot Example: >>> single_boxplot(x='group', y='value', ax=ax, data=df, annotation=True, stripplot=True) .. py:function:: configure_subplot_grid(N: Optional[int] = None, wh: Optional[float] = None, w: float = 8, h: float = 8, sharex: bool = False, sharey: bool = False, Ncols: Optional[int] = None, Nrows: Optional[int] = None, Nrows_coef: int = 1, figsize: Optional[Tuple[int, int]] = None, **kwargs: Any) -> Dict[str, Any] Calculate grid dimensions and configure subplot grid parameters. Determines optimal number of rows and columns for arranging N elements in a grid, with customizable figure sizing and axis sharing. Args: N: Total number of elements. Defaults to None wh: Width and height for each subplot. Defaults to None w: Width for each subplot when wh is not specified. Defaults to 8 h: Height for each subplot when wh is not specified. Defaults to 8 sharex: Share the x-axis among subplots. Defaults to False sharey: Share the y-axis among subplots. Defaults to False Ncols: Number of columns for the subplot grid. Defaults to None Nrows: Number of rows for the subplot grid. Defaults to None Nrows_coef: Coefficient to adjust the number of rows. Defaults to 1 figsize: Figure size (width, height). Defaults to None **kwargs: Additional keyword arguments passed to subplot creation function Returns: Dictionary of keyword arguments for configuring subplots including nrows, ncols, figsize, sharex, and sharey Example: >>> kws = configure_subplot_grid(N=6, wh=5, sharex=True, Ncols=3) .. py:function:: define_end_ks(ks: Optional[Sequence[str]] = None, mode: str = 'basic') -> Sequence[str] Define endpoint parameter shortcuts for different analysis modes. Returns predefined sets of endpoint parameter keys based on analysis mode (basic, minimal, tiny, etc.) or custom list. Args: ks: Custom parameter shortcuts. Uses mode-specific set if None mode: Analysis mode ('basic', 'minimal', 'tiny', 'deb', etc.). Defaults to 'basic' Returns: List of parameter shortcut keys Example: >>> ks = define_end_ks(mode='minimal') >>> ks = define_end_ks(ks=['fsv', 'sv_mu', 'cum_sd']) .. py:function:: get_vs(datasets: Sequence[Any], par: str, key: str = 'step', absolute: bool = False, rad2deg: bool = False) -> List[numpy.ndarray] Extract parameter values from multiple datasets. Collects parameter arrays from datasets with optional transformations (absolute values, radian to degree conversion). Args: datasets: List of datasets to extract from par: Parameter name to extract key: Data key ('step', 'end', etc.). Defaults to 'step' absolute: Use absolute values. Defaults to False rad2deg: Convert radians to degrees. Defaults to False Returns: List of numpy arrays containing parameter values Example: >>> values = get_vs(datasets=[d1, d2], par='v', key='step', absolute=True) .. py:function:: color_epochs(epochs: Sequence[Tuple[int, int]], ax: matplotlib.axes.Axes, trange: Sequence[float], edgecolor: str = f'{0.4 * (0 + 1)}', facecolor: str = 'lightblue', epoch_boundaries: bool = True, epoch_area: bool = True) -> None Color behavioral epochs on time series plot. Adds colored background regions and boundary lines for behavioral epochs (strides, pauses, turns) on existing axes. Args: epochs: List of (start, end) index tuples ax: Matplotlib axes to annotate trange: Time array corresponding to indices edgecolor: Color for epoch boundaries. Defaults to gray facecolor: Fill color for epoch regions. Defaults to 'lightblue' epoch_boundaries: Show vertical lines at boundaries. Defaults to True epoch_area: Fill epoch regions with color. Defaults to True Example: >>> color_epochs([(10, 20), (30, 40)], ax, time_array, facecolor='green')