lunapi.viz ========== .. py:module:: lunapi.viz .. autoapi-nested-parse:: Visualization helpers for notebook workflows. Exports plotting utilities for hypnograms, spectra, topographic maps, and the interactive ``scope`` viewer built on ``ipywidgets`` and Plotly. Functions --------- .. autoapisummary:: lunapi.viz.default_xy lunapi.viz.stgcol lunapi.viz.stgn lunapi.viz.hypno lunapi.viz.hypno_density lunapi.viz.psd lunapi.viz.spec lunapi.viz.spec0 lunapi.viz.topo_heat lunapi.viz.scope Module Contents --------------- .. py:function:: default_xy() Return default 2-D scalp electrode locations for a standard 64-channel EEG montage. :returns: DataFrame with columns ``['CH', 'X', 'Y']`` giving the normalised Cartesian coordinates of each electrode (top-down view, nose pointing up). :rtype: pandas.DataFrame .. py:function:: stgcol(ss) Map a sequence of sleep stage labels to their canonical hex display colours. :param ss: Sleep stage labels (e.g. ``['W', 'N1', 'N2', 'R', '?']``). :type ss: list of str :returns: Hex colour string for each label (e.g. ``'#0050C8FF'`` for N2). Unknown labels are returned unchanged. :rtype: list of str .. py:function:: stgn(ss) Map a sequence of sleep stage labels to their canonical numeric codes. Codes: N1 → −1, N2 → −2, N3 → −3, R → 0, W → 1, L/? → 2. :param ss: Sleep stage labels. :type ss: list of str :returns: Numeric stage code for each label. Unknown labels are returned unchanged. :rtype: list of int .. py:function:: hypno(ss, e=None, xsize=20, ysize=2, title=None) Plot a colour-coded hypnogram from a sequence of sleep stage labels. :param ss: Per-epoch sleep stage labels (e.g. from :meth:`~lunapi.instance.inst.stages`). :type ss: array-like of str :param e: Epoch indices. If omitted, epochs are numbered ``0, 1, 2, …``. Values are divided by 120 before plotting to convert to hours (assuming 30-second epochs). :type e: array-like of int, optional :param xsize: Figure width in inches. Default ``20``. :type xsize: float, optional :param ysize: Figure height in inches. Default ``2``. :type ysize: float, optional :param title: Optional plot title. :type title: str, optional :returns: The hypnogram is rendered inline via Matplotlib. :rtype: None .. py:function:: hypno_density(probs, e=None, xsize=20, ysize=2, title=None) Plot a stacked-probability hypno-density chart from POPS/SOAP output. Displays per-epoch posterior stage probabilities as a stacked area plot, giving an at-a-glance picture of staging confidence across the night. :param probs: DataFrame containing columns ``PP_N1``, ``PP_N2``, ``PP_N3``, ``PP_R``, and ``PP_W`` (as returned by the POPS command). :type probs: pandas.DataFrame :param e: Reserved for future use; currently unused. :type e: ignored, optional :param xsize: Figure width in inches. Default ``20``. :type xsize: float, optional :param ysize: Figure height in inches. Default ``2``. :type ysize: float, optional :param title: Optional plot title. :type title: str, optional :returns: The chart is rendered inline via Matplotlib. :rtype: None .. py:function:: psd(df, ch, var='PSD', minf=None, maxf=None, minp=None, maxp=None, xlines=None, ylines=None, dB=False) Plot power spectral density from a Luna ``PSD`` or ``MTM`` ``CH_F`` table. :param df: Result table with at least columns ``'CH'``, ``'F'``, and the power variable named by *var*. Typically the ``'PSD: CH_F'`` or ``'MTM: CH_F'`` table returned by :meth:`~lunapi.instance.inst.proc`. :type df: pandas.DataFrame :param ch: Channel label(s) to plot. :type ch: str or list of str :param var: Column name containing the power values (``'PSD'`` or ``'MTM'``). Default ``'PSD'``. :type var: str, optional :param minf: Minimum frequency (Hz) for the x-axis. Default: data minimum. :type minf: float, optional :param maxf: Maximum frequency (Hz) for the x-axis. Default: data maximum. :type maxf: float, optional :param minp: Minimum power for the y-axis. Default: data minimum. :type minp: float, optional :param maxp: Maximum power for the y-axis. Default: data maximum. :type maxp: float, optional :param xlines: Vertical reference lines at these frequencies. :type xlines: float or list of float, optional :param ylines: Horizontal reference lines at these power values. :type ylines: float or list of float, optional :param dB: If ``True``, convert power values to dB (10·log₁₀) before plotting. Default ``False``. :type dB: bool, optional :returns: The plot is rendered inline via Matplotlib. :rtype: None .. py:function:: spec(df, ch=None, var='PSD', mine=None, maxe=None, minf=None, maxf=None, w=0.025) Plot an epoch-by-frequency spectrogram from a Luna ``CH_E_F`` result table. :param df: Result table with columns ``'E'`` (epoch), ``'F'`` (frequency), ``'CH'`` (channel), and the power variable named by *var*. Typically the ``'PSD: CH_E_F'`` or ``'MTM: CH_E_F'`` table. :type df: pandas.DataFrame :param ch: Channel to plot. If ``None``, all channels in *df* are included. :type ch: str, optional :param var: Column name for power values. Default ``'PSD'``. :type var: str, optional :param mine: First epoch to display. Default: first epoch in the data. :type mine: int, optional :param maxe: Last epoch to display. Default: last epoch in the data. :type maxe: int, optional :param minf: Minimum frequency (Hz). Default: data minimum. :type minf: float, optional :param maxf: Maximum frequency (Hz). Default: data maximum. :type maxf: float, optional :param w: Winsorisation proportion applied to power values before colour mapping. Default ``0.025``. :type w: float, optional :returns: The spectrogram is rendered inline via Matplotlib. :rtype: None .. py:function:: spec0(x, y, z, mine, maxe, minf, maxf) Render a 2-D spectrogram heatmap from raw epoch/frequency/value vectors. Low-level helper called by :func:`spec`. Bins *z* values into an epoch × frequency grid and displays the result as a ``pcolormesh`` plot. :param x: Epoch index for each observation. :type x: array-like of int :param y: Frequency (Hz) for each observation. :type y: array-like of float :param z: Power value for each observation. :type z: array-like of float :param mine: Minimum epoch index for the x-axis. :type mine: int :param maxe: Maximum epoch index for the x-axis. :type maxe: int :param minf: Minimum frequency (Hz) for the y-axis. :type minf: float :param maxf: Maximum frequency (Hz) for the y-axis. :type maxf: float :returns: The heatmap is rendered inline via Matplotlib. :rtype: None .. py:function:: topo_heat(chs, z, ths=None, th=0.05, topo=None, lmts=None, sz=70, colormap='bwr', title='', rimcolor='black', lab='dB') Plot a channel-wise topographic heat map on a scalp electrode layout. Renders a scatter plot in electrode space where each dot is coloured by the scalar value *z* for that channel. Channels with an associated p-value below *th* are drawn with a thicker rim. :param chs: Channel labels corresponding to each value in *z*. :type chs: array-like of str :param z: Scalar values to colour-map (one per channel in *chs*). :type z: array-like of float :param ths: P-values (or thresholding values) for each channel. Channels with ``ths < th`` receive a highlighted rim. Default ``None`` (no thresholding). :type ths: array-like of float, optional :param th: Significance threshold applied to *ths*. Default ``0.05``. :type th: float, optional :param topo: Electrode coordinate table with columns ``['CH', 'X', 'Y']``. Defaults to the 64-channel layout from :func:`default_xy`. :type topo: pandas.DataFrame, optional :param lmts: ``[vmin, vmax]`` colour-map limits. Default: ``[min(z), max(z)]``. :type lmts: list of two float, optional :param sz: Marker size (points²) for each electrode dot. Default ``70``. :type sz: float, optional :param colormap: Matplotlib colour map name. Default ``'bwr'``. :type colormap: str, optional :param title: Text label placed in the upper-left of the figure. Default ``''``. :type title: str, optional :param rimcolor: Edge colour for all electrode markers. Default ``'black'``. :type rimcolor: str, optional :param lab: Colour-bar label. Default ``'dB'``. :type lab: str, optional :returns: The topoplot is rendered inline via Matplotlib. :rtype: None .. py:function:: scope(p, chs=None, bsigs=None, hsigs=None, anns=None, stgs=['N1', 'N2', 'N3', 'R', 'W', '?', 'L'], stgcols={'N1': 'blue', 'N2': 'blue', 'N3': 'navy', 'R': 'red', 'W': 'green', '?': 'gray', 'L': 'yellow'}, stgns={'N1': -1, 'N2': -2, 'N3': -3, 'R': 0, 'W': 1, '?': 2, 'L': 2}, sigcols=None, anncols=None, throttle1_sr=100, throttle2_np=5 * 30 * 100, summary_mins=30, height=600, annot_height=0.15, header_height=0.04, footer_height=0.01) Create the interactive notebook scope viewer for one instance. :param p: Target Luna instance. :type p: inst :param chs: Signal channel selections for traces/bands/Hjorth summaries. :type chs: list of str, optional :param bsigs: Signal channel selections for traces/bands/Hjorth summaries. :type bsigs: list of str, optional :param hsigs: Signal channel selections for traces/bands/Hjorth summaries. :type hsigs: list of str, optional :param anns: Annotation classes to include. :type anns: list of str, optional :param stgs: Sleep-stage labels used by hypnogram rendering. :type stgs: list of str, optional :param stgcols: Stage-to-color and stage-to-numeric maps. :type stgcols: dict, optional :param stgns: Stage-to-color and stage-to-numeric maps. :type stgns: dict, optional :param sigcols: Optional explicit color overrides. :type sigcols: dict, optional :param anncols: Optional explicit color overrides. :type anncols: dict, optional :param throttle1_sr: Input sample-rate throttle. :type throttle1_sr: int, optional :param throttle2_np: Output point-count throttle. :type throttle2_np: int, optional :param summary_mins: Threshold (minutes) for summary behavior in backend. :type summary_mins: int or float, optional :param height: Main scope plot height. :type height: int, optional :param annot_height: Relative layout proportions. :type annot_height: float, optional :param header_height: Relative layout proportions. :type header_height: float, optional :param footer_height: Relative layout proportions. :type footer_height: float, optional :returns: Widget application, or ``None`` when no valid channels/annots exist. :rtype: ipywidgets.AppLayout or None