"""
This submodule provides essential plotting functions for visualizing passive acoustics 
data. The functions allow for customizable plotting of sound pressure spectral density 
levels across time and frequency dimensions.
Each plotting function leverages the flexibility of Matplotlib, allowing for passthrough
of Matplotlib keyword arguments via ``**kwargs``, making it easy to modify plot aspects such as
color, scale, and label formatting.
Key Functions
-------------
1. **plot_spectrogram**:
   - Generates a spectrogram plot from sound pressure spectral density level data, 
     with a logarithmic frequency scale by default for improved readability of acoustic data.
2. **plot_spectra**:
   - Produces a spectral density plot with a log-transformed x-axis, allowing for clear 
     visualization of spectral density across frequency bands.
"""
from typing import Tuple
import xarray as xr
import matplotlib.pyplot as plt
from .analysis import _fmax_warning
[docs]
def plot_spectrogram(
    spsdl: xr.DataArray,
    fmin: int = 10,
    fmax: int = 100000,
    fig: plt.figure = None,
    ax: plt.Axes = None,
    **kwargs
) -> Tuple[plt.figure, plt.Axes]:
    """
    Plots the spectrogram of the sound pressure spectral density level.
    Parameters
    ----------
    spsdl: xarray DataArray (time, freq)
        Mean square sound pressure spectral density level in dB rel 1 uPa^2/Hz
    fmin: int
        Lower frequency band limit (lower limit of the hydrophone). Default: 10 Hz
    fmax: int
        Upper frequency band limit (Nyquist frequency). Default: 100000 Hz
    fig: matplotlib.pyplot.figure
        Figure handle to plot on
    ax: matplotlib.pyplot.axis
        Figure axis containing plot objects
    kwargs: dict
        Dictionary of matplotlib function keyword arguments
    Returns
    -------
    fig: matplotlib.pyplot.figure
        Figure handle of plot
    ax: matplotlib.pyplot.Axes
        Figure plot axis
    """
    if not isinstance(fmin, (int, float)) or not isinstance(fmax, (int, float)):
        raise TypeError("fmin and fmax must be numeric types.")
    if fmin >= fmax:
        raise ValueError("fmin must be less than fmax.")
    # Set dimension names
    # "time" or "time_bins" is always first
    time = spsdl.dims[0]
    # "freq" or "freq_bins" is always second
    freq = spsdl.dims[-1]
    # Check fmax
    fn = spsdl[freq].max().item()
    fmax = _fmax_warning(fn, fmax)
    # select frequency range
    spsdl = spsdl.sel({freq: slice(fmin, fmax)})
    if ax is None:
        fig, ax = plt.subplots(figsize=(6, 5), subplot_kw={"yscale": "log"})
        fig.subplots_adjust(left=0.1, right=0.95, top=0.97, bottom=0.11)
    h = ax.pcolormesh(
        spsdl[time].values,
        spsdl[freq].values,
        spsdl.transpose(freq, time),
        shading="nearest",
        **kwargs
    )
    fig.colorbar(h, ax=ax, label=getattr(spsdl, "units", None))
    ax.set(xlabel="Time", ylabel="Frequency [Hz]")
    return fig, ax 
[docs]
def plot_spectra(
    spsdl: xr.DataArray,
    fmin: int = 10,
    fmax: int = 100000,
    fig: plt.figure = None,
    ax: plt.Axes = None,
    **kwargs
) -> Tuple[plt.figure, plt.Axes]:
    """
    Plots spectral density. X axis is log-transformed.
    Parameters
    ----------
    spsdl: xarray DataArray (time, freq)
        Mean square sound pressure spectral density level in dB rel 1 uPa^2/Hz
    fmin: int
        Lower frequency band limit (lower limit of the hydrophone). Default: 10 Hz
    fmax: int
        Upper frequency band limit (Nyquist frequency). Default: 100000 Hz
    fig: matplotlib.pyplot.figure
        Figure handle to plot on
    ax: matplotlib.pyplot.Axes
        Figure axis containing plot objects
    kwargs: dict
        Dictionary of matplotlib function keyword arguments
    Returns
    -------
    fig: matplotlib.pyplot.figure
        Figure handle of plot
    ax: matplotlib.pyplot.Axes
        Figure plot axis
    """
    if not isinstance(fmin, (int, float)) or not isinstance(fmax, (int, float)):
        raise TypeError("fmin and fmax must be numeric types.")
    if fmin >= fmax:
        raise ValueError("fmin must be less than fmax.")
    # Set dimension names.
    # "freq" or "freq_bins" is always second
    freq = spsdl.dims[-1]
    # Check fmax
    fn = spsdl[freq].max().item()
    fmax = _fmax_warning(fn, fmax)
    # select frequency range
    spsdl = spsdl.sel({freq: slice(fmin, fmax)})
    if ax is None:
        fig, ax = plt.subplots(figsize=(6, 5), subplot_kw={"xscale": "log"})
        fig.subplots_adjust(
            left=0.1, right=0.95, top=0.85, bottom=0.2, hspace=0.3, wspace=0.15
        )
    ax.plot(spsdl[freq], spsdl.T, **kwargs)
    ax.set(
        xlim=(fmin, fmax), xlabel="Frequency [Hz]", ylabel=getattr(spsdl, "units", None)
    )
    return fig, ax