coco_pipe.viz.dim_reduction =========================== .. py:module:: coco_pipe.viz.dim_reduction .. autoapi-nested-parse:: Matplotlib visualization helpers for dimensionality reduction outputs. Functions --------- .. autoapisummary:: coco_pipe.viz.dim_reduction.plot_embedding coco_pipe.viz.dim_reduction.plot_metrics coco_pipe.viz.dim_reduction.plot_loss_history coco_pipe.viz.dim_reduction.plot_eigenvalues coco_pipe.viz.dim_reduction.plot_shepard_diagram coco_pipe.viz.dim_reduction.plot_streamlines coco_pipe.viz.dim_reduction.plot_feature_importance coco_pipe.viz.dim_reduction.plot_feature_correlation_heatmap coco_pipe.viz.dim_reduction.plot_trajectory_metric_series coco_pipe.viz.dim_reduction.plot_trajectory coco_pipe.viz.dim_reduction.plot_coranking_matrix coco_pipe.viz.dim_reduction.plot_trajectory_separation coco_pipe.viz.dim_reduction.plot_component_loadings coco_pipe.viz.dim_reduction.plot_phase_portrait coco_pipe.viz.dim_reduction.plot_scree Module Contents --------------- .. py:function:: plot_embedding(X_emb, labels = None, metadata = None, dims = (0, 1), title = 'Embedding', figsize = (10, 8), cmap = None, palette = 'deep', s = 40, alpha = 0.8, label_kind = 'categorical', metrics = None, metric_name = None, ax = None, random_state = None) Plot an explicit 2D or 3D embedding. :param X_emb: Embedding array with shape ``(n_samples, n_dimensions)``. :param labels: Optional label array aligned with samples used for color encoding. :param metadata: Optional column-oriented metadata aligned with samples. :param dims: Column indices to use as plot axes. Two indices produce a 2D plot; three produce a 3D plot. :param title: Axes title. :param figsize: Figure size used when creating new axes. :param cmap: Colormap used when ``label_kind="continuous"``. :param palette: Seaborn palette name used when ``label_kind="categorical"``. :param s: Scatter marker size. :param alpha: Scatter point opacity. :param label_kind: ``"categorical"`` to color by class, ``"continuous"`` to apply a colormap to numeric labels. :param metrics: Optional metrics mapping used to annotate the plot when ``metric_name`` is provided. :param metric_name: Name of the metric from ``metrics`` to display as an annotation. :param ax: Existing Matplotlib axes to draw into. :param random_state: Accepted for API compatibility; not used internally. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_embedding` Interactive Plotly version. :py:obj:`plot_metrics` Quality metric overview for the embedding run. :py:obj:`plot_shepard_diagram` Distance-preservation diagnostic. :py:obj:`plot_eigenvalues` Explained variance for linear reducers. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> X_emb = rng.normal(size=(50, 2)) >>> labels = np.arange(50) % 5 >>> fig, ax = viz.plot_embedding(X_emb, labels=labels) .. py:function:: plot_metrics(scores, title = 'Quality Metrics', figsize = (8, 6), ax = None, plot_type = 'bar', metric = None, scope = None, method = None, axes_kws = None) Plot tidy metric observations using one shared entrypoint. :param scores: Metric source: a tidy DataFrame, ``{metric: value}`` mapping, list of records, or any object exposing ``to_frame()`` or ``metrics_``. :param title: Axes title. :param figsize: Figure size used when creating new axes. :param ax: Existing Matplotlib axes to draw into. :param plot_type: Visualization style. ``"bar"`` / ``"grouped_bar"`` / ``"lollipop"`` aggregate to global scalars; ``"box"`` / ``"boxen"`` / ``"violin"`` / ``"raincloud"`` / ``"strip"`` / ``"swarm"`` show per-observation distributions; ``"heatmap"`` produces a method x metric grid; ``"line"`` plots metrics across a numeric scope axis; ``"dumbbell"`` / ``"slopegraph"`` require exactly two methods. :param metric: Optional metric name used to filter rows before plotting. :param scope: Optional scope name used to filter rows before plotting. :param method: Optional method name or names used to filter rows before plotting. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_metrics` Interactive Plotly version. :py:obj:`plot_embedding` 2D or 3D scatter of the embedding points. :py:obj:`plot_eigenvalues` Per-component explained variance. :py:obj:`plot_coranking_matrix` Neighbourhood-preservation co-ranking heatmap. .. rubric:: Examples >>> from coco_pipe.viz import dim_reduction as viz >>> fig, ax = viz.plot_metrics({"trustworthiness": 0.92, "continuity": 0.88}) .. py:function:: plot_loss_history(loss_history, title = 'Training Loss', figsize = (8, 5), ax = None, scope = None, axes_kws = None) Plot reducer loss history. Linear reducers usually do not expose this. :param loss_history: Sequence of per-epoch loss values from an iterative reducer. :param title: Axes title. :param figsize: Figure size used when creating new axes. :param ax: Existing Matplotlib axes to draw into. :param scope: Optional scope tag, accepted as ``"train"`` or ``"val"``. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] :raises ValueError: If ``loss_history`` is empty or ``scope`` is not ``"train"`` or ``"val"``. .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_loss_history` Interactive Plotly version. :py:obj:`plot_eigenvalues` Explained variance for linear reducers. :py:obj:`plot_metrics` Scalar quality metric overview. .. rubric:: Examples >>> from coco_pipe.viz import dim_reduction as viz >>> fig, ax = viz.plot_loss_history([1.0, 0.7, 0.4, 0.25, 0.18]) .. py:function:: plot_eigenvalues(values, title = 'Scree Plot', ylabel = 'Explained Variance', figsize = (8, 5), ax = None, max_components = None, condition_colors = None, axes_kws = None) Plot explained variance curves from linear reducers (PCA, TruncatedSVD). :param values: Mapping of label → array. Array shapes: - 1-D ``(n_pcs,)`` — pre-averaged curve, no SEM band. - 2-D ``(n_subjects, n_pcs)`` — per-subject data; mean ± SEM band drawn. :type values: dict[str, np.ndarray] :param max_components: Cap the number of components shown. :type max_components: int, optional :param condition_colors: Per-label hex colour overrides. :type condition_colors: dict[str, str], optional .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_eigenvalues` Interactive Plotly version. :py:obj:`plot_metrics` Scalar quality metric overview. :py:obj:`plot_loss_history` Iterative training loss curve. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> evals = {"PCA": np.array([0.50, 0.30, 0.12, 0.05, 0.03])} >>> fig, ax = viz.plot_eigenvalues(evals) .. py:function:: plot_shepard_diagram(X_orig, X_emb, sample_size = 1000, title = 'Shepard Diagram', ax = None, random_state = None, distances = None, figsize = None) Plot original vs embedded pairwise distances. :param X_orig: Original high-dimensional data with shape ``(n_samples, n_features)``. Ignored when ``distances`` is provided. :param X_emb: Low-dimensional embedding with shape ``(n_samples, n_dims)``. Ignored when ``distances`` is provided. :param sample_size: Number of point pairs to sample for distance computation. :param title: Axes title. :param ax: Existing Matplotlib axes to draw into. :param random_state: Random seed for reproducible distance sampling. :param distances: Pre-computed distance dict with ``"original"`` and ``"embedded"`` keys. When both keys are present, ``X_orig`` and ``X_emb`` are not used. :param figsize: Figure size used when creating new axes. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_shepard_diagram` Interactive Plotly version. :py:obj:`plot_embedding` Scatter of the low-dimensional embedding. :py:obj:`plot_coranking_matrix` Neighbourhood-rank preservation heatmap. :py:obj:`plot_metrics` Scalar quality metrics such as trustworthiness. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> X_orig = rng.normal(size=(60, 10)) >>> X_emb = rng.normal(size=(60, 2)) >>> fig, ax = viz.plot_shepard_diagram(X_orig, X_emb, sample_size=200) .. py:function:: plot_streamlines(X_emb, V_emb, grid_density = 25, title = 'Velocity Streamlines', ax = None, random_state = None, figsize = None) Plot a velocity field on a 2D embedding. :param X_emb: 2D embedding coordinates with shape ``(n_samples, 2)``. :param V_emb: Velocity vectors with the same shape as ``X_emb``, as returned by ``coco_pipe.dim_reduction.evaluation.velocity.compute_velocity_fields``. :param grid_density: Number of grid points per axis used for velocity interpolation. :param title: Axes title. :param ax: Existing Matplotlib axes to draw into. :param random_state: Accepted for API compatibility; not used internally. :param figsize: Figure size used when creating new axes. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_streamlines` Interactive Plotly version. :py:obj:`plot_embedding` Scatter of the underlying embedding points. :py:obj:`plot_trajectory` Plotted trajectory paths over the embedding. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> X_emb = rng.normal(size=(80, 2)) >>> V_emb = rng.normal(size=(80, 2)) * 0.2 >>> fig, ax = viz.plot_streamlines(X_emb, V_emb) .. py:function:: plot_feature_importance(scores, title = 'Feature Importance', top_n = 20, figsize = (8, 6), ax = None, analysis = None, method = None, dimension = None) Plot feature-importance scores as horizontal bars. :param scores: Feature-score source: a raw ``{feature: score}`` mapping, interpretation payload, tidy interpretation DataFrame, or any object exposing ``interpretation_``. :param title: Axes title. :param top_n: Maximum number of features to display, ranked by score magnitude. :param figsize: Figure size used when creating new axes. :param ax: Existing Matplotlib axes to draw into. :param analysis: Interpretation analysis to select when multiple analyses are present. :param method: Method name to select when multiple methods are present. :param dimension: Dimension label to select when multiple dimensions are present. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_feature_importance` Interactive Plotly version. :py:obj:`plot_feature_correlation_heatmap` Feature-to-dimension correlation heatmap. :py:obj:`plot_component_loadings` Linear-reducer component loading matrix. .. rubric:: Examples >>> from coco_pipe.viz import dim_reduction as viz >>> scores = {"alpha": 0.72, "beta": 0.55, "gamma": 0.31} >>> fig, ax = viz.plot_feature_importance(scores) .. py:function:: plot_feature_correlation_heatmap(correlations, title = 'Feature Correlation', top_n = 25, figsize = (10, 8), ax = None, method = None) Plot feature-to-dimension correlations as a heatmap. :param correlations: Correlation source: a raw correlation payload, tidy interpretation DataFrame, or any object exposing ``interpretation_``. :param title: Axes title. :param top_n: Maximum number of features to show, ranked by peak absolute correlation across dimensions. :param figsize: Figure size used when creating new axes. :param ax: Existing Matplotlib axes to draw into. :param method: Method name to select when multiple methods are present. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_feature_correlation_heatmap` Interactive Plotly version. :py:obj:`plot_feature_importance` Ranked feature-importance bar chart. :py:obj:`plot_component_loadings` Linear-reducer component loading matrix. .. rubric:: Examples >>> from coco_pipe.viz import dim_reduction as viz >>> payload = { ... "correlation": {"D1": {"F1": 0.6, "F2": -0.3}, "D2": {"F1": 0.1, "F2": 0.8}} ... } >>> fig, ax = viz.plot_feature_correlation_heatmap(payload) .. py:function:: plot_trajectory_metric_series(series, times = None, labels = None, color_map = None, linestyle_map = None, smooth_window = 1, title = 'Trajectory Metric', ylabel = 'Value', figsize = (10, 6), ax = None) Plot evaluated trajectory metric time series. :param series: Metric values: a 1D array, 2D ``(trajectory, time)`` array, or a ``{name: timecourse}`` mapping. 2D arrays are averaged across trajectories per unique label. :param times: Explicit time axis aligned with the time dimension. :param labels: Trajectory labels aligned with the first axis of 2D inputs. :param title: Axes title. :param ylabel: Y-axis label. :param figsize: Figure size used when creating new axes. :param ax: Existing Matplotlib axes to draw into. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_trajectory_metric_series` Interactive Plotly version. :py:obj:`plot_trajectory` Raw trajectory paths in embedding space. :py:obj:`plot_trajectory_separation` Pairwise label-separation timecourses. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> series = rng.normal(size=(3, 20)) >>> fig, ax = viz.plot_trajectory_metric_series(series) .. py:function:: plot_trajectory(X, times = None, values = None, labels = None, color_map = None, linestyle_map = None, smooth_window = 1, downsample = 1, speed_mode = 'linecollection', add_start_end_markers = False, show_markers = True, xlim = None, ylim = None, linewidth = 2.5, title = 'Trajectory Plot', dimensions = 2, figsize = (10, 8), ax = None, cmap = None, axis_labels = None, axes_kws = None, showlegend = True) Plot prepared trajectory tensors of shape ``trajectory x time x dim``. :param X: Each trajectory along the first axis — can be individual subjects, pre-averaged conditions, or any other grouping. :type X: np.ndarray of shape (n_trajectories, n_times, n_dims) :param times: Time stamps for the time axis. Defaults to integer indices. :type times: np.ndarray, optional :param values: Per-point scalar values (e.g. speed) used for colour encoding. :type values: np.ndarray of shape (n_trajectories, n_times), optional :param labels: Label per trajectory used for colouring and legend. :type labels: array-like of length n_trajectories, optional :param color_map: Optional mapping of label to hex color string. :type color_map: dict[str, str], optional :param linestyle_map: Optional mapping of label to Matplotlib linestyle string. :type linestyle_map: dict[str, str], optional :param smooth_window: Moving-average window applied before plotting. :type smooth_window: int, default=1 :param downsample: Keep every ``downsample``-th time point. :type downsample: int, default=1 :param speed_mode: Colour-encoding style when ``values`` is provided (2D only). ``"linecollection"`` colours each segment by value; ``"alpha"`` modulates transparency and lightness of the base colour. :type speed_mode: {"linecollection", "alpha"}, default="linecollection" :param add_start_end_markers: Draw a circle (●) at the start and a cross (✕) at the end of each trajectory instead of a marker on every point. :type add_start_end_markers: bool, default=False :param show_markers: If True, draws markers at each sampled time point unless ``add_start_end_markers`` is True. :type show_markers: bool, default=True :param xlim: Fixed axis limits. Auto-scaled when ``None``. :type xlim: tuple[float, float], optional :param ylim: Fixed axis limits. Auto-scaled when ``None``. :type ylim: tuple[float, float], optional :param linewidth: :type linewidth: float, default=2.5 :param title: :type title: str, default="Trajectory Plot" :param dimensions: Number of spatial dimensions to render (2 or 3). :type dimensions: int, default=2 :param figsize: :type figsize: tuple[float, float], optional :param ax: :type ax: matplotlib.axes.Axes, optional :param cmap: Colormap name for value encoding. Defaults to the theme sequential map. :type cmap: str, optional :param axis_labels: Custom axis labels (e.g. ``["PC1", "PC2"]``). :type axis_labels: list[str], optional :param axes_kws: Additional kwargs passed to ``ax.set()``. :type axes_kws: dict, optional :param showlegend: Whether to draw the legend. :type showlegend: bool, default=True .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_trajectory` Interactive Plotly version. :py:obj:`plot_trajectory_separation` Pairwise label-separation timecourses. :py:obj:`plot_trajectory_metric_series` Metric time series for trajectories. :py:obj:`plot_streamlines` Velocity field overlay on the embedding. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> X = rng.normal(size=(3, 20, 2)) >>> labels = np.array(["A", "B", "C"]) >>> fig, ax = viz.plot_trajectory(X, labels=labels) .. py:function:: plot_coranking_matrix(coranking_matrix, title = 'Co-Ranking Matrix', max_k = None, ax = None, figsize = None) Heatmap of a co-ranking matrix produced by ``DimReduction.score()``. :param coranking_matrix: Square co-ranking matrix with shape ``(n_samples-1, n_samples-1)``. :param title: Axes title. :param max_k: Crop the matrix to the top-left ``max_k x max_k`` corner. Defaults to ``min(n, 50)``. :param ax: Existing Matplotlib axes to draw into. :param figsize: Figure size used when creating new axes. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_coranking_matrix` Interactive Plotly version. :py:obj:`plot_shepard_diagram` Continuous distance-preservation scatter. :py:obj:`plot_metrics` Scalar quality metric overview. :py:obj:`plot_embedding` Low-dimensional scatter being diagnosed. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> Q = np.random.default_rng(42).integers(0, 10, size=(15, 15)).astype(float) >>> fig, ax = viz.plot_coranking_matrix(Q) .. py:function:: plot_trajectory_separation(separation, times = None, top_n = None, color_map = None, linestyle_map = None, smooth_window = 1, ax = None, figsize = None) Pairwise label-separation timecourses for trajectory embeddings. :param separation: Mapping of ``(label_a, label_b)`` tuples (or any hashable key) to 1D separation timecourses, as returned by ``DimReduction.evaluate_trajectory``. :param times: Explicit time axis aligned with the separation arrays. :param top_n: Keep only the ``top_n`` pairs ranked by peak separation. :param color_map: Optional mapping of pair key to color. :param linestyle_map: Optional mapping of pair key to linestyle. :param ax: Existing Matplotlib axes to draw into. :param figsize: Figure size used when creating new axes. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_trajectory_separation` Interactive Plotly version. :py:obj:`plot_trajectory` Raw trajectory paths in embedding space. :py:obj:`plot_trajectory_metric_series` Metric time series for trajectories. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> sep = { ... ("A", "B"): np.linspace(0.1, 0.9, 20), ... ("A", "C"): np.linspace(0.3, 0.6, 20), ... } >>> fig, ax = viz.plot_trajectory_separation(sep) .. py:function:: plot_component_loadings(components, feature_names = None, n_components = None, center = 0.0, ax = None, figsize = None) Heatmap of component loadings from linear reducers. :param components: Loading matrix with shape ``(n_features, n_components)``. :param feature_names: Optional feature names for row labels. Defaults to ``["Feature 0", "Feature 1", ...]``. :param n_components: Crop to this many components (columns). :param center: Colormap center value for the diverging palette. :param ax: Existing Matplotlib axes to draw into. :param figsize: Figure size used when creating new axes. :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_component_loadings` Interactive Plotly version. :py:obj:`plot_feature_importance` Ranked feature-importance bar chart. :py:obj:`plot_feature_correlation_heatmap` Feature-to-dimension correlation heatmap. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> components = rng.normal(size=(12, 3)) >>> fig, ax = viz.plot_component_loadings(components) .. py:function:: plot_phase_portrait(X, times, labels, component_idx = 0, title = 'Phase Portrait', figsize = (8, 10), ax = None, axes_kws = None) Plot a phase portrait (amplitude vs velocity) for condition-mean trajectories. :param X: Trajectory array with shape ``(n_conditions, n_times, n_components)``. :type X: np.ndarray :param times: One-dimensional time axis aligned with the time dimension of ``X``. :type times: np.ndarray :param labels: Condition labels, one per trajectory (first axis of ``X``). :type labels: sequence :param component_idx: Index of the component to extract for the portrait. :type component_idx: int, default=0 :param title: Axes title. :type title: str, default="Phase Portrait" :param figsize: Figure size used when creating new axes. :type figsize: tuple[float, float], optional :param ax: Existing Matplotlib axes to draw into. :type ax: matplotlib.axes.Axes, optional :returns: The created or reused figure and axes. :rtype: tuple[matplotlib.figure.Figure, matplotlib.axes.Axes] .. seealso:: :py:obj:`coco_pipe.viz.interactive.dim_reduction.plot_phase_portrait` Interactive Plotly version. :py:obj:`plot_trajectory` Full trajectory geometry in 2D or 3D space. :py:obj:`plot_trajectory_metric_series` Scalar metric timecourses per trajectory. .. rubric:: Examples >>> import numpy as np >>> from coco_pipe.viz import dim_reduction as viz >>> rng = np.random.default_rng(42) >>> X = rng.normal(size=(3, 20, 5)) >>> times = np.linspace(0, 1, 20) >>> fig, ax = viz.plot_phase_portrait(X, times, labels=["A", "B", "C"]) .. py:function:: plot_scree(evr, title = 'Scree Plot', figsize = (8, 10), ax = None, axes_kws = None) Creates a scree plot. Plots individual explained variance as bars and cumulative variance as a line.