Source code for Modules.CurveBoxplot.curve_boxplot

from .curve_boxplot_stats import curve_boxplot_summary_statistics
from .curve_boxplot_mesh import curve_boxplot_mesh
from .curve_boxplot_vis import visualize_curve_boxplot
from uvisbox.Core.CommonInterface import BoxplotStyleConfig
import numpy as np
import matplotlib.pyplot as plt

[docs] def curve_boxplot(curves, boxplot_style=None, ax=None, workers=12): """ Create a curve band depth plot with multiple percentile bands. This function follows a 3-stage pipeline: statistics → mesh → visualization. It computes curve band depths, generates triangular meshes for percentile bands, and creates a visualization with median and outlier curves. For 2D curves, uses matplotlib. For 3D curves, uses PyVista if available, otherwise falls back to matplotlib. Parameters: ----------- curves : numpy.ndarray 3D array of shape (n_curves, n_steps, n_dims) containing curve data. Input data is not modified (computation happens on a copy). boxplot_style : BoxplotStyleConfig, optional Configuration for the boxplot visualization including percentiles, colors, and median/outlier styling. If None, uses default configuration. ax : matplotlib.axes.Axes or pyvista.Plotter, optional Axes or plotter to plot on. Can be either: - matplotlib.axes.Axes for 2D or 3D matplotlib rendering - pyvista.Plotter for 3D PyVista rendering If None, creates appropriate visualization object automatically. workers : int, optional Number of worker processes for parallel computation of band depths. Default is 12. Set to 1 or None to use sequential processing (useful for debugging). Returns: -------- ax : matplotlib.axes.Axes or pyvista.Plotter The visualization object (matplotlib axes for 2D, PyVista plotter for 3D if available). Notes: ------ - The function does not modify the input curves array - Bands are plotted from largest to smallest percentile for proper layering - The median curve is the curve with the highest depth value - Outliers are curves beyond the largest percentile - Curve depths are always computed internally - For 3D curves, PyVista provides better interactivity than matplotlib Examples: --------- >>> # Basic usage with defaults >>> ax = curve_boxplot(curves) >>> # Custom styling >>> from uvisbox.Core.CommonInterface import BoxplotStyleConfig >>> style = BoxplotStyleConfig( ... percentiles=[10, 50, 90], ... percentile_colors=['lightblue', 'blue', 'darkblue'], ... show_median=True, ... median_color='red', ... show_outliers=True ... ) >>> ax = curve_boxplot(curves, boxplot_style=style) >>> # 3D curves with PyVista >>> import pyvista as pv >>> plotter = pv.Plotter() >>> curve_boxplot(curves_3d, ax=plotter) >>> plotter.show() >>> # Hide median and outliers >>> style = BoxplotStyleConfig(show_median=False, show_outliers=False) >>> ax = curve_boxplot(curves, boxplot_style=style) """ # Use default config if none provided if boxplot_style is None: boxplot_style = BoxplotStyleConfig() # Validate input data if not isinstance(curves, np.ndarray): curves = np.array(curves) if curves.ndim != 3: raise ValueError(f"Input curves must be a 3D array of shape (n_curves, n_steps, n_dims). Got {curves.ndim}D array.") # Pipeline: Stats -> Mesh -> Vis # Step 1: Compute summary statistics stats = curve_boxplot_summary_statistics(curves, boxplot_style=boxplot_style, workers=workers) # Step 2: Build triangular mesh mesh_data = curve_boxplot_mesh(stats) # Step 3: Visualize result = visualize_curve_boxplot(mesh_data, boxplot_style=boxplot_style, ax=ax) return result