Skip to content

plasma_plots.spectral_plots

Plots of the spectral diagnostics in plasma_plots.spectral.

Each returns a PlotResult, whose data holds what was drawn.

Attributes

NameDescription
OMEGANo description.

Functions

NameDescription
plot_boozer_spectrumThe strongest Boozer harmonics of |B| over the radius, and the quasi-symmetry error.
plot_cross_spectrumPlot the magnitude (and coherence, if present) and phase of a cross-spectrum.
plot_filteredPlot a probe of the signal (minus its mean) against its filtered reconstruction.
plot_mode_amplitudesPlot the amplitude of the strongest (m, n) modes over time, optionally with growth fits.
plot_mode_mapPlot |amplitude| over the (m, n) plane of a mode spectrum.
plot_mode_profilesPlot the radial eigenfunction of each harmonic: |amplitude| (and phase) against x.
plot_pencil_fitPlot a matrix_pencil() fit and its complex frequencies.
plot_power_spectrumPlot the power per frequency bin, averaged over dims, one line per remaining coordinate.
plot_radial_powerPlot where each frequency lives: power over (omega, x), e.g. radius, with continua.
plot_spectrogramPlot a (t, omega) spectrogram from spectrogram().

OMEGAattributemodule attribute#

OMEGA = '$\\omega$'

plot_boozer_spectrumfunction#

def plot_boozer_spectrum(data: xr.DataArray, *, top: int = 8, helicity=None, log: bool = True, angles: str = 'boozer', x_of=None, xlabel: str | None = None, title: str | None = None)

The strongest Boozer harmonics of |B| over the radius, and the quasi-symmetry error.

One line per harmonic (m, n) (n the full-torus mode number, in the convention of boozer_spectrum()). With helicity the symmetry-breaking harmonics are dashed, and a second panel shows the quasi-symmetry error quasisymmetry_error() over the radius.

Parameters

NameTypeDefaultDescription
dataxarray.DataArrayrequired|B| on a Boozer grid, over (rho, theta_B, zeta_B).
topint8The number of harmonics drawn, strongest first. Default: 8.
helicity('QA', 'QP', 'QH')"QA"The symmetry to judge against (see quasisymmetry_error()). Default: none.
logboolTrueA logarithmic amplitude axis. Default: True.
angles('boozer', 'any')"boozer"As for boozer_spectrum().
x_ofcallableNoneMaps the radial coordinate to the plotted axis, e.g. lambda rho: a * rho.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s.
titlestrNoneThe title. Default: the harmonics’ label.

Returns

PlotResult
The figure, the axes (one, or two with helicity) and the lines; data holds the amplitudes and, with helicity, the error.

Examples

>>> plot_boozer_spectrum(boozer.mod_B, top=8, helicity="QA")

plot_cross_spectrumfunction#

def plot_cross_spectrum(cross: xr.Dataset, *, omega_max: float | None = None, title: str | None = None)

Plot the magnitude (and coherence, if present) and phase of a cross-spectrum.

The top panel shows the magnitude on a log axis spanning 6 decades, with the coherence on a second axis; the bottom panel the phase in degrees at bins with at least 1e-3 of the peak magnitude (elsewhere the phase is noise), with the phase at the peak marked.

Parameters

NameTypeDefaultDescription
crossxarray.DatasetrequiredA cross_spectrum() result reduced to omega only (e.g. summed over dims).
omega_maxfloatNoneThe highest frequency shown. Default: all.
titlestrNoneThe title. Default: the phase’s label.

Returns

PlotResult
The figure, the two axes and the drawn lines; data holds peak_omega and peak_phase_deg, the frequency and phase (in degrees) of the strongest bin.

Raises

ValueError
If dimensions other than omega remain.

Examples

>>> plot_cross_spectrum(
... cross_spectrum(phi, density, dims=["eta1", "eta2", "eta3"]),
... omega_max=3.0,
... )

plot_filteredfunction#

def plot_filtered(data: xr.DataArray, result, *, ax=None, **selection)

Plot a probe of the signal (minus its mean) against its filtered reconstruction.

Parameters

NameTypeDefaultDescription
dataxarray.DataArrayrequiredThe original signal, with a t dimension.
resultTimeFilterResult or xarray.DataArrayrequiredA TimeFilterResult or a filtered array (e.g. from band_filter()) on the grid of data.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
**selection{}Every dimension but t, selected by keyword: an integer is a position (-1 the last), a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the two lines (signal minus mean, filtered).

Raises

ValueError
If a dimension other than t remains after the selection.

Examples

>>> result = filter_time(phi)
>>> plot_filtered(phi, result, eta1=0.5, eta2=0, eta3=0)

plot_mode_amplitudesfunction#

def plot_mode_amplitudes(modes: xr.DataArray, *, top: int = 6, fit=None, logy: bool = True, ax=None, title: str = 'Mode amplitudes')

Plot the amplitude of the strongest (m, n) modes over time, optionally with growth fits.

Parameters

NameTypeDefaultDescription
modesxarray.DataArrayrequiredmode_spectrum() output (complex, turned into real amplitudes by mode_amplitudes()) or mode_amplitudes output, reduced to (t, m, n) or (t, mode): average or select other dimensions (e.g. eta1) first.
topint6The number of modes drawn, those with the largest peak amplitude. Default: 6.
fit(float, float) or boolNoneFit an exponential growth rate γ to each mode: a time window (t0, t1), or True for the whole record. Default: no fit.
logyboolTrueLogarithmic amplitude axis. Default: True.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestr'Mode amplitudes'The axes title. Default: "Mode amplitudes".

Returns

PlotResult
The figure, the axes and the drawn lines. fit_results holds one growth fit per drawn mode (None without fit); data holds the plotted amplitudes.

Raises

ValueError
If dimensions other than t and the mode numbers remain.

Examples

>>> modes = mode_spectrum(phi).max("eta1")
>>> plot_mode_amplitudes(modes, top=4, fit=(0.0, 20.0)).fit_results[0].rate

plot_mode_mapfunction#

def plot_mode_map(modes: xr.DataArray, *, m_range: tuple[int, int] | None = None, n_range: tuple[int, int] | None = None, log: bool = True, cmap='viridis', ax=None, title: str | None = None)

Plot |amplitude| over the (m, n) plane of a mode spectrum.

Parameters

NameTypeDefaultDescription
modesxarray.DataArrayrequiredmode_spectrum() output reduced to (m, n): select a time and average or select everything else first.
m_range(int, int)NoneThe range of m shown, both ends included. Default: all.
n_range(int, int)NoneThe range of n shown, both ends included. Default: all.
logboolTrueColor by log10(|amplitude|), clipped at 4 decades below the maximum. Default: True.
cmapstr or matplotlib.colors.Colormap'viridis'The colormap. Default: "viridis".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: the spectrum’s label.

Returns

PlotResult
The figure, the axes and the mesh; data holds the plotted amplitude.

Raises

ValueError
If modes has dimensions other than m and n.

Examples

>>> plot_mode_map(
... mode_spectrum(phi).isel(t=-1).sel(eta1=0.5, method="nearest"),
... m_range=(-8, 8),
... )

plot_mode_profilesfunction#

def plot_mode_profiles(structure: xr.DataArray, *, x: str | None = None, x_of=None, xlabel: str | None = None, top: int = 4, phase: bool = True, title: str | None = None)

Plot the radial eigenfunction of each harmonic: |amplitude| (and phase) against x.

The phase panel (unwrapped, in radians) shows whether the harmonics oscillate together, as the coupled harmonics of a global eigenmode do. Phases are drawn only where a harmonic has at least 5% of its peak amplitude.

Parameters

NameTypeDefaultDescription
structurexarray.DataArrayrequiredComplex over (x, m, n): typically mode_spectrum(mode_structure(field, omega)), the complex amplitude of each poloidal harmonic at one frequency. Or real over (x, mode), e.g. mode_amplitudes of one snapshot’s mode spectrum, which has no phase panel.
xstrNoneThe radial dimension. Default: the radial logical one (eta1, or GVEC’s rho).
x_ofcallableNoneMaps the x coordinate to the plotted axis, e.g. lambda eta1: 0.1 + 0.9 * eta1. The axis is then labeled r.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s label, or r with x_of.
topint4The number of strongest harmonics drawn; (m, n) and (-m, -n) count as one (the stronger is drawn, labeled by the half whose first nonzero number is positive). Default: 4.
phaseboolTrueAdd the phase panel (only for complex structure). Default: True.
titlestrNoneThe title. Default: the structure’s label.

Returns

PlotResult
The figure, the array of axes (amplitude, then phase) and the drawn lines; data holds the plotted profiles.

Raises

ValueError
If structure has dimensions other than x and the mode numbers.

Examples

>>> plot_mode_profiles(
... mode_spectrum(mode_structure(phi, 0.42)).isel(n=0), top=3
... )

plot_pencil_fitfunction#

def plot_pencil_fit(data: xr.DataArray, fit: xr.Dataset, *, title: str | None = None)

Plot a matrix_pencil() fit and its complex frequencies.

The left panel shows the signal against its reconstruction; the right panel the fitted modes in the complex-frequency plane (ω against γ; above zero grows, below is damped), sized by amplitude.

Parameters

NameTypeDefaultDescription
dataxarray.DataArrayrequiredThe real (t,) series that was fitted.
fitxarray.DatasetrequiredIts matrix_pencil() fit.
titlestrNoneThe title of the signal panel. Default: the array’s label.

Returns

PlotResult
The figure, the two axes and the drawn artists; data holds the fit and the reconstructed model.

Examples

>>> series = energy.sel(t=slice(0.0, 5.0))
>>> plot_pencil_fit(series, matrix_pencil(series, n_modes=2))

plot_power_spectrumfunction#

def plot_power_spectrum(data, *, dims=None, detrend: bool = True, window: str | None = None, peaks: int | None = None, band=None, frequencies: dict | None = None, logy: bool = True, dynamic_range: float | None = 8.0, omega_max: float | None = None, ax=None, title: str | None = None)

Plot the power per frequency bin, averaged over dims, one line per remaining coordinate.

Parameters

NameTypeDefaultDescription
dataxarray.DataArray or xarray.DatasetrequiredA real signal with a t dimension (transformed by time_fft() with detrend and window), a time_fft Dataset (its power is drawn), or an array over omega: power, or complex coefficients (e.g. a two-sided fft()), drawn as their squared magnitude.
dimsstr or sequence of strNoneDimensions to average the power over. At most one other dimension may remain, which gives one line per coordinate value. Default: every dimension but omega and component.
detrendboolTrueSubtract the signal’s mean before transforming. Default: True.
window(None, 'hann')NoneWindow applied before transforming a signal. Default: None.
peaksintNoneMark and label this many of the strongest peaks of a single line, with sub-bin frequencies (see spectral_peaks()). Default: none.
band(TimeFilterResult, xarray.Dataset or (float, float))NoneA frequency band to shade: a filter_time() result or its spectrum (with one band selected), or an (omega_lo, omega_hi) pair.
frequenciesdictNoneNamed reference frequencies drawn as vertical dotted lines, e.g. {"gap": 0.8} for a continuum-gap estimate.
logyboolTrueLogarithmic power axis. Default: True.
dynamic_rangefloat8.0With logy, the number of decades shown below the peak (a removed mean leaves a near-zero DC bin). None for Matplotlib’s limits. Default: 8.0.
omega_maxfloatNoneThe highest frequency shown. Default: all.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: the power’s label.

Returns

PlotResult
The figure, the axes and the drawn artists; data holds the plotted power and the peaks Dataset (None without peaks).

Raises

ValueError
If more than one dimension besides omega remains, or peaks is given for several lines.

Examples

>>> plot_power_spectrum(
... phi.isel(eta2=0, eta3=0), peaks=2, frequencies={"theory": 1.2}
... )

plot_radial_powerfunction#

def plot_radial_power(power: xr.DataArray, *, x: str | None = None, x_of=None, xlabel: str | None = None, continuum=None, log: bool = True, dynamic_range: float = 3.0, omega_max: float | None = None, cmap='magma', ax=None, title: str | None = None)

Plot where each frequency lives: power over (omega, x), e.g. radius, with continua.

A global eigenmode shows as a horizontal ridge in a continuum gap; a continuum-damped oscillation follows the continuum curves.

Parameters

NameTypeDefaultDescription
powerxarray.DataArray or xarray.DatasetrequiredA time_fft() Dataset or power array reduced to (omega, x): average the angles away first.
xstrNoneThe spatial dimension. Default: the radial logical one (eta1, or GVEC’s rho).
x_ofcallableNoneMaps the x coordinate to the plotted axis, e.g. lambda eta1: 0.1 + 0.9 * eta1 for the minor radius of a hollow torus. The axis is then labeled r.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s label, or r with x_of.
continuumtuple or xarray.DataArrayNoneContinuous spectra overlaid as curves: a (spectrum, modes) pair as for plot_continuous_spectrum(), evaluated on the plotted axis, or a (mode, branch, x) array from prepare_continuous_spectrum().
logboolTrueColor by log10(power), clipped at dynamic_range decades below the maximum. Default: True.
dynamic_rangefloat3.0With log, the number of decades shown. Default: 3.0.
omega_maxfloatNoneThe highest frequency shown. Default: all.
cmapstr or matplotlib.colors.Colormap'magma'The colormap. Default: "magma".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: "Radial power".

Returns

PlotResult
The figure, the axes, the mesh and the continuum curves; data holds the plotted power.

Raises

ValueError
If power has dimensions other than omega and x.

Examples

>>> power = time_fft(phi, detrend=True).power.mean(["eta2", "eta3"])
>>> plot_radial_power(power, x_of=lambda eta1: 0.1 + 0.9 * eta1, omega_max=2.0)

plot_spectrogramfunction#

def plot_spectrogram(power: xr.DataArray, *, log: bool = True, dynamic_range: float = 4.0, omega_max: float | None = None, frequencies: dict | None = None, cmap='magma', ax=None, title: str | None = None)

Plot a (t, omega) spectrogram from spectrogram().

Parameters

NameTypeDefaultDescription
powerxarray.DataArrayrequiredThe spectrogram, reduced to (t, omega): average any further dimensions away first.
logboolTrueColor by log10(power). Default: True.
dynamic_rangefloat4.0With log, the number of decades the colors span below the maximum. Default: 4.0.
omega_maxfloatNoneThe highest frequency shown. Default: all.
frequenciesdictNoneNamed reference frequencies drawn as horizontal dotted lines.
cmapstr or matplotlib.colors.Colormap'magma'The colormap. Default: "magma".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: the spectrogram’s label.

Returns

PlotResult
The figure, the axes, the mesh and the reference lines; data holds the plotted spectrogram.

Raises

ValueError
If power has dimensions other than t and omega.

Examples

>>> plot_spectrogram(
... spectrogram(phi.isel(eta1=8, eta2=0, eta3=0), length=10.0)
... )