Skip to content

plasma_plots.accessors

The .plasma accessor: plots, diagnostics and plot data of a single labeled array or dataset.

Every product of an [Output][struphy.Output] carries this accessor after importing plasma_plots, and so does every array derived from one:

  • array.plasma.plot ([ArrayPlots][ArrayPlots]), array.plasma.analysis ([ArrayAnalysis][ArrayAnalysis]) and array.plasma.data ([ArrayData][ArrayData]) for an xarray.DataArray;
  • dataset.plasma.plot ([DatasetPlots][DatasetPlots]), dataset.plasma.analysis ([DatasetAnalysis][DatasetAnalysis]) and dataset.plasma.data ([DatasetData][DatasetData]) for an xarray.Dataset, e.g. an orbits product.

Dimensions that are neither displayed nor swept are selected by naming them: an integer is a position (t=0 the first, t=-1 the last), and a float is the nearest coordinate value (t=0.35).

Examples

>>> import plasma_plots
>>> phi.plasma.plot.slice(x="eta1", y="eta2", t=-1)
>>> energy.plasma.analysis.growth_rate(window=(0.0, 5.0))
>>> orbits.plasma.plot.trajectories()

Attributes

NameDescription
BackendNo description.
CoordinatesNo description.
PlaneNo description.

Classes

NameDescription
ArrayAnalysisQuantitative diagnostics of one array, as array.plasma.analysis.<quantity>(...).
ArrayDataThe data behind each plot in ArrayPlots, without rendering it.
ArrayPlotsPlots of one array, as array.plasma.plot.<kind>(...).
DatasetAnalysisQuantitative diagnostics of one dataset, as dataset.plasma.analysis.<quantity>(...).
DatasetDataThe data behind each plot in DatasetPlots, without rendering it.
DatasetPlotsPlots of one dataset, as dataset.plasma.plot.<kind>(...).
PlasmaAccessorStruphy diagnostics of one array: array.plasma.plot, .analysis and .data.
PlasmaDatasetAccessorStruphy diagnostics of one dataset, e.g. an orbits product: dataset.plasma.plot.
SliceViewA configured array view, shared by static, interactive and exported plots.

Backendattributemodule attribute#

Backend = Literal['matplotlib', 'plotly', 'tikz']

Coordinatesattributemodule attribute#

Coordinates = Literal['logical', 'physical']

Planeattributemodule attribute#

Plane = Literal['XY', 'XZ', 'YZ', 'RZ', 'X1X2']

ArrayAnalysisclass#

class ArrayAnalysis(_ArrayAccessor)

Bases: _ArrayAccessor

Quantitative diagnostics of one array, as array.plasma.analysis.<quantity>(...).

Each method applies a function of plasma_plots.analysis or plasma_plots.spectral to this array; see there for the definitions and conventions.

Examples

>>> energy.plasma.analysis.growth_rate(window=(0.0, 5.0))
>>> phi.plasma.analysis.time_fft(detrend=True)

band_filtermethod#

def band_filter(omega_lo: float, omega_hi: float, *, detrend: bool = False) -> xr.DataArray

Return only the frequencies in [omega_lo, omega_hi].

Parameters

NameTypeDefaultDescription
omega_lofloatrequiredThe lowest angular frequency kept.
omega_hifloatrequiredThe highest angular frequency kept, at least omega_lo.
detrendboolFalseSubtract the temporal mean first; the result then has zero mean even if the band includes DC. Default: False.

Returns

xarray.DataArray
The filtered signal, on this array’s grid.

Examples

>>> phi.plasma.analysis.band_filter(0.08, 0.11)

boozer_spectrummethod#

def boozer_spectrum(top: int | None = None, angles: str = 'boozer') -> xr.DataArray

Return the Boozer harmonics B_mn of this quantity over the radius.

Parameters

NameTypeDefaultDescription
topintNoneKeep only the top harmonics with the largest peak amplitude over the radius, strongest first. Default: all.
angles('boozer', 'any')"boozer"Require the Boozer angles theta_B, zeta_B (default), or take the harmonics in whatever angles the field has (not a Boozer spectrum then; e.g. for a comparison).

Returns

xarray.DataArray
The real amplitudes over mode (with m, n) and the radius.

Examples

>>> boozer.mod_B.plasma.analysis.boozer_spectrum(top=8)

critical_pointsmethod#

def critical_points(refine: bool = True) -> xr.Dataset

Return the O-points and X-points of this flux function (at every time).

Parameters

NameTypeDefaultDescription
refineboolTrueLocate the zero within the cell by Newton’s method (the cell’s centre otherwise). Default: True.

Returns

xarray.Dataset
The points over point (and t): positions, values and kinds.

Examples

>>> B.plasma.analysis.flux_function().plasma.analysis.critical_points()

cross_spectrummethod#

def cross_spectrum(other: xr.DataArray, *, dims=None, detrend: bool = True, window=None) -> xr.Dataset

Return the cross-spectrum, phase (of other relative to this) and coherence.

Parameters

NameTypeDefaultDescription
otherxarray.DataArrayrequiredThe second signal, on the same time grid; its phase is relative to this one.
dimsstr or sequence of strNoneDimensions to sum the cross-spectrum over, as an ensemble. Default: none (no coherence).
detrendboolTrueSubtract each signal’s temporal mean first. Default: True.
window(None, 'hann')NoneWindow applied to both signals before transforming. Default: None.

Returns

xarray.Dataset
The cross-spectrum, phase and (with dims) coherence over omega.

Examples

>>> u.plasma.analysis.cross_spectrum(b, dims="eta3")

curlmethod#

def curl(components: str = 'cartesian', domain=None) -> xr.DataArray

Return the curl of this vector field, in Cartesian components.

Parameters

NameTypeDefaultDescription
components('cartesian', 'contravariant')"cartesian"What the components are: "cartesian" (default) (x, y, z), or "contravariant" components, which are pushed forward first.
domainstruphy domainNoneThe mapping (out.domain), for the exact Jacobian. Default: from the X, Y, Z coordinates.

Returns

xarray.DataArray
The curl, with a component dimension.

Examples

>>> B.plasma.analysis.curl()

cylindrical_componentsmethod#

def cylindrical_components() -> xr.DataArray

Return the Cartesian components rotated to (R, phi, Z).

Returns

xarray.DataArray
The vector field in cylindrical components.

Examples

>>> E.plasma.analysis.cylindrical_components()

damping_ratemethod#

def damping_rate(window: tuple[float | None, float | None] = (None, None), amplitude: bool = False)

Fit exponential decay to the envelope of this oscillating time series.

Parameters

NameTypeDefaultDescription
window(float or None, float or None)(None, None)The time interval (t0, t1) of the peaks that are used; None for an open end. Default: every sample.
amplitudeboolFalseThe series is quadratic in an amplitude (e.g. an energy): return the amplitude’s rate. Default: False.

Returns

FitResult or None
The fit to the peaks; the rate is negative for damping. None with fewer than two valid peaks.

Examples

>>> energy.plasma.analysis.damping_rate(amplitude=True).rate

dispersionmethod#

def dispersion(dim: str | None = None, detrend: bool = True) -> xr.DataArray

Return the space-time power spectrum of this (t, dim) field.

A plain FFT, as a function of angular frequency and wavenumber: the data behind a dispersion-relation plot (ArrayPlots.dispersion()). dim defaults to the sole dimension other than t; select every other dimension away first. omega comes out in the angular-frequency units implied by t’s spacing (e.g. rad/s for physical seconds, or a normalized angular frequency for normalized time).

Parameters

NameTypeDefaultDescription
dimstrNoneThe spatial dimension. Default: the sole dimension other than t.
detrendboolTrueRemove the time-mean at each point of dim first, which otherwise dominates the spectrum as a spurious zero-frequency line. Default: True.

Returns

xarray.DataArray
The power over omega and the wavenumber.

Examples

>>> spectrum = E.isel(eta2=0, eta3=0).plasma.analysis.dispersion()

divergencemethod#

def divergence(components: str = 'cartesian', domain=None) -> xr.DataArray

Return the divergence of this vector field.

Parameters

NameTypeDefaultDescription
components('cartesian', 'contravariant')"cartesian"What the components are, as for the 3-D views: "cartesian" (default) (x, y, z), or "contravariant" components, which are pushed forward first.
domainstruphy domainNoneThe mapping (out.domain), for the exact Jacobian. Default: from the X, Y, Z coordinates.

Returns

xarray.DataArray
The divergence, without the component dimension.

Examples

>>> B.plasma.analysis.divergence()

driftmethod#

def drift(ref=None) -> xr.DataArray

Return the signed deviation of this time series from ref or from its first sample.

Parameters

NameTypeDefaultDescription
reffloat or array_like or xarray.DataArrayNoneThe reference, broadcast against data. Default: data at the first time sample.

Returns

xarray.DataArray
The deviation over t.

Examples

>>> energy.plasma.analysis.drift().plasma.plot.timeseries()

drop_periodic_endpointmethod#

def drop_periodic_endpoint(dim: str, *, period: float = 1.0) -> xr.DataArray

Return this array without a duplicated periodic endpoint along dim.

Parameters

NameTypeDefaultDescription
dimstrrequiredThe periodic dimension.
periodfloat1.0The period in the coordinate of dim. Default: 1.0.

Returns

xarray.DataArray
This array, one point shorter along dim if its last point repeats the first.

envelopemethod#

def envelope() -> xr.DataArray

Return the local maxima of this time series.

Returns

xarray.DataArray
The peaks, over their times t.

errormethod#

def error(exact, *, norm: str = 'rms', relative: bool = False, dims=None, weighted: bool = False, domain=None, args=None) -> xr.DataArray

Return the error against an exact solution (an array or a function of the coordinates).

Parameters

NameTypeDefaultDescription
exact(callable, array_like, number or xarray.DataArray)requiredThe exact solution: an array (aligned with data, or broadcast to it) or a function of its coordinates, evaluated with [evaluate_on()][evaluate_on], e.g. lambda x, y, z, t: ....
norm('rms', 'max', 'l1', 'l2', 'pointwise')"rms""pointwise" is the difference data − exact itself; "max" the largest absolute difference; "l1" the mean (or, weighted, the integral) of |data − exact|; "l2" the square root of the mean (or integral) of |data − exact|²; "rms" (default) as "l2", divided by the volume when weighted.
relativeboolFalseDivide by the same norm of the exact solution; for "pointwise", by the largest |exact| over the whole array. Default: False.
dimsstr or sequence of strNoneThe dimensions the norm is taken over. Default: every dimension but t. Weighted norms need exactly eta1, eta2, eta3.
weightedboolFalseIntegrate over the physical volume instead of averaging over the grid points (no effect on "max" and "pointwise"). Default: False.
domainstruphy domainNoneThe mapping (out.domain), for the exact |√g| of weighted norms. Default: from the X, Y, Z coordinates.
argssequence of strNoneThe coordinates passed to a callable exact, as in [evaluate_on()][evaluate_on]. Default: X, Y, Z (or the logical dimensions), then t.

Returns

xarray.DataArray
The error, over the dimensions not reduced by norm.

Examples

>>> T.plasma.analysis.error(exact, relative=True)
>>> T.plasma.analysis.error(exact, norm="max")

fftmethod#

def fft(dim: str, detrend: bool = False, window: str | None = None) -> xr.DataArray

Return the two-sided Fourier coefficients along dim.

Parameters

NameTypeDefaultDescription
dimstrrequiredThe dimension to transform.
detrendboolFalseSubtract the mean along dim first. Default: False.
window(None, 'hann')NoneMultiply by a periodic Hann window (see [hann()][hann]) first. Default: None (boxcar).

Returns

xarray.DataArray
The complex coefficients.

Examples

>>> phi.plasma.analysis.fft(dim="eta1")

field_linesmethod#

def field_lines(seeds=8, turns: float | None = None, length: float | None = None, step: float | None = None, direction: str = 'forward', section: float | None = None, stride: int | None = None, components: str = 'cartesian', **selection) -> xr.Dataset

Trace field lines of this vector field through its mapped grid.

Parameters

NameTypeDefaultDescription
seeds(int, dict, array_like or xarray.Dataset)8Where the lines start, in logical coordinates: a number of seeds spread along the radial coordinate at the first poloidal and toroidal grid values (the outboard midplane of a torus whose angles start at 0); a dict of logical coordinates to values or 1-D arrays, which are combined into a grid of seeds (e.g. {"rho": 0.95, "theta": thetas, "zeta": zetas} for a connection-length map; a missing coordinate takes its first grid value); an (n, 3) array of points in the order of the logical dimensions; or a Dataset with one variable per logical coordinate. Default: 8.
turnsfloatNoneStop a line after this many toroidal transits (turns of the torus: nfp periods of the toroidal logical coordinate, i.e. 2π of GVEC’s toroidal angle, one period of Struphy’s eta3). Default: 20 when the toroidal direction wraps around, else none.
lengthfloatNoneStop a line after this arc length, in the units of X, Y, Z. Default: with turns, 1.5 times the length turns circles through the seeds’ mean major radius would take (a safety net); without, four times the grid’s extent.
stepfloatNoneThe step of arc length of the integrator. Default: the median spacing of the grid points (trilinear interpolation limits the accuracy before the step does).
direction('forward', 'backward', 'both')"forward"Along the field, against it, or each seed in both directions (two lines per seed, with the coordinates seed and direction telling them apart; the connection length is then the sum of both). Default: "forward".
sectionfloatNoneThe toroidal logical coordinate of the poloidal plane whose punctures are recorded. Default: the first toroidal grid value (e.g. zeta = 0).
strideintNoneSave every stride-th step of each line. Default: as many as keep each line at about 20 000 samples at most; the punctures, transits and lengths count every step regardless.
components('cartesian', 'contravariant')"cartesian"What the components are: "cartesian" (default) (x, y, z), or contravariant logical components, as for plasma_plots.analysis.divergence().
**selection{}The other dimensions, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

xarray.Dataset
The lines over (s, line) with their punctures, rotational transforms and connection lengths; it has .plasma.plot.poincare(), .footprint() and the other field-line plots.

Examples

>>> lines = B.plasma.analysis.field_lines(seeds=12, turns=100, t=-1)
>>> lines.plasma.plot.poincare(color_by="iota")
>>> edge = B.plasma.analysis.field_lines(
... seeds={"eta1": 0.98, "eta2": np.linspace(0, 1, 32)},
... direction="both",
... t=-1,
... )

filter_timemethod#

def filter_time(dims=None, omega_min: float = 1e-08, pad_bins: int = 0)

Return the dominant frequency band, reconstructed.

Parameters

NameTypeDefaultDescription
dimsstr or sequence of strNoneNon-time dimensions to sum the power over before choosing the band. Default: all dimensions except t and component. Pass dims=() for independent filtering at each point.
omega_minfloat1e-08Finite, positive lowest frequency considered, which excludes DC. Default: 1e-8.
pad_binsint0Nonnegative number of extra bins on each side of the band. Default: 0.

Returns

TimeFilterResult
The band and the reconstructed signal.

Examples

>>> band = phi.plasma.analysis.filter_time(dims=("eta1", "eta2", "eta3"))

fit_branchesmethod#

def fit_branches(n_branches: int, k_range: tuple[float, float] | None = None, noise_level: float = 0.5, order: int = 10)

Fit straight dispersion branches (omega = v * k) to this (omega, k) power spectrum.

Parameters

NameTypeDefaultDescription
n_branchesintrequiredThe number of branches, at least 1.
k_range(float, float)NoneThe interval of non-negative k’s that are scanned. Default: (k.max() / 8, k.max() / 2), which in practice skips both the low-k region where branches have not yet separated, and the folded Nyquist edge.
noise_levelfloat0.5Maxima count only above this fraction of the column’s peak power. Default: 0.5.
orderint10A local maximum must exceed every one of its order neighbors on both sides along omega (out-of-range neighbors are clipped to the edge sample, as in scipy.signal.argrelextrema). Default: 10.

Returns

list of BranchFit
One fit per branch.

Examples

>>> field.plasma.analysis.dispersion().plasma.analysis.fit_branches(
... n_branches=2
... )

flux_functionmethod#

def flux_function() -> xr.DataArray

Return the flux (or stream) function of this 2-D in-plane field.

Returns

xarray.DataArray
The flux function, without the component dimension.

Examples

>>> B.plasma.analysis.flux_function()

gradientmethod#

def gradient(domain=None) -> xr.DataArray

Return the Cartesian gradient of this scalar field on a mapped domain.

Parameters

NameTypeDefaultDescription
domainstruphy domainNoneThe mapping (out.domain), for the exact Jacobian. Default: differentiate the X, Y, Z coordinates numerically.

Returns

xarray.DataArray
The gradient, with a component dimension (x, y, z).

Examples

>>> phi.plasma.analysis.gradient()

growth_ratemethod#

def growth_rate(window: tuple[float | None, float | None] = (None, None), amplitude: bool = False)

Fit exp(rate * t + intercept) to this time series within window.

Parameters

NameTypeDefaultDescription
window(float or None, float or None)(None, None)The time interval (t0, t1) of the fitted samples; None for an open end. Default: every sample.
amplitudeboolFalseThe series is quadratic in an amplitude (e.g. an energy): return the amplitude’s rate. Default: False.

Returns

FitResult or None
.rate, .intercept, .time and .fitted; None with fewer than two valid samples.

Examples

>>> energy.plasma.analysis.growth_rate(window=(0.0, 5.0), amplitude=True).rate

map_coordinatemethod#

def map_coordinate(dim: str, mapping, *, name: str | None = None, units: str | None = None, label: str | None = None) -> xr.DataArray

Replace a coordinate by a function of it, e.g. eta1 by the minor radius in meters.

Parameters

NameTypeDefaultDescription
dimstrrequiredThe dimension whose coordinate is mapped, e.g. "eta1".
mappingcallable or floatrequiredA function of the coordinate’s values (lambda eta1: 0.1 + 0.9 * eta1), or a factor (a length, for length * eta1).
namestrNoneThe name of the new dimension, e.g. "r". Default: keep dim.
unitsstrNoneThe new coordinate’s units, e.g. "m". Default: none.
labelstrNoneThe new coordinate’s axis label (its long_name), mathtext allowed. Default: name.

Returns

xarray.DataArray
The array over the new coordinate, which every plot then draws and labels.

Examples

>>> r_T = T.plasma.analysis.map_coordinate(
... "eta1", lambda eta1: 0.1 + 0.9 * eta1, name="r", units="m"
... )
>>> r_T.plasma.plot.profiles(x="r", eta2=0, eta3=0)

matrix_pencilmethod#

def matrix_pencil(n_modes: int = 1, pencil: int | None = None, detrend: bool = False) -> xr.Dataset

Return frequencies and growth rates beyond the FFT resolution.

Parameters

NameTypeDefaultDescription
n_modesint1The number of modes to fit and return: real oscillations for a real signal, complex exponentials for a complex one. The fit needs well over 2 * n_modes samples. Default: 1.
pencilintNoneThe pencil parameter (Hankel matrix width minus one), which trades noise robustness against resolution. Default: N // 2.
detrendboolFalseSubtract the mean first. Default: False.

Returns

xarray.Dataset
omega, gamma, amplitude and phase along mode, strongest first.

Examples

>>> probe.plasma.analysis.matrix_pencil(n_modes=1)

mode_amplitudesmethod#

def mode_amplitudes(top: int | None = None, real: bool = True, relative: bool = False) -> xr.DataArray

Return the real amplitudes of this mode spectrum along one mode dimension.

Parameters

NameTypeDefaultDescription
topintNoneKeep only the top modes with the largest peak amplitude over every other dimension, strongest first. Default: all modes.
realboolTrueThe field is real: each (m, n) is combined with its conjugate (-m, -n). Only the half with the first nonzero mode number positive is kept, and its amplitude doubled, so a field A cos(...) gives A. A mode without a twin on the grid (the mean, or the Nyquist mode of an even grid) is kept as it is. Default: True.
relativeboolFalseDivide by the amplitude of the mean (the mode with all numbers zero), which is then left out: e.g. density perturbations relative to the background density, as growth plots of an instability often show. NaN where the mean vanishes. Default: False.

Returns

xarray.DataArray
The amplitudes over mode and every remaining dimension.

Examples

>>> phi.plasma.analysis.mode_spectrum().plasma.analysis.mode_amplitudes(top=4)

mode_spectrummethod#

def mode_spectrum(dims=None, names=('m', 'n'), periods=None, scale=None) -> xr.DataArray

Return the complex amplitudes over poloidal/toroidal mode numbers.

Parameters

NameTypeDefaultDescription
dimsstr or sequence of strNoneThe periodic dimensions to transform. Default: the two angles of the logical dimensions (see plasma_plots.arrays.logical_dims()), ("eta2", "eta3") for Struphy.
namesstr or sequence of str('m', 'n')The name of the mode number of each dimension, one per dimension. Default: ("m", "n").
periodsfloat or sequence of floatNoneEach direction’s period in its coordinate: one number for all, or one per dimension. Default: the coordinate’s period attribute (see plasma_plots.arrays.angle_period()), else 1.0.
scaleint or sequence of intNoneMultiplies the mode numbers (one number, or one per dimension; cast to integers), e.g. scale=(1, 6) labels a sixth of a torus (Struphy’s tor_period=6) with full-torus toroidal mode numbers. Default: 2π over the period attribute of an angle (nfp for GVEC’s toroidal angle), else 1.

Returns

xarray.DataArray
The amplitudes over the mode numbers names and every remaining dimension.

Examples

>>> modes = phi.plasma.analysis.mode_spectrum()

mode_structuremethod#

def mode_structure(omega: float, *, window: str | None = 'hann', detrend: bool = True) -> xr.DataArray

Return the complex amplitude at the exact frequency omega at every point.

Parameters

NameTypeDefaultDescription
omegafloatrequiredThe angular frequency ω.
window('hann', None)"hann"The weights w(t): a periodic Hann window, or None for uniform weights. Default: "hann".
detrendboolTrueSubtract the temporal mean at every point first. Default: True.

Returns

xarray.DataArray
The complex amplitude over every dimension but t.

Examples

>>> phi.plasma.analysis.mode_structure(omega)

normmethod#

def norm(dims=None, squared: bool = False) -> xr.DataArray

Return the L2 norm over dims (default: every dimension except t).

Parameters

NameTypeDefaultDescription
dimsstr or sequence of strNoneThe dimensions summed over. Default: every dimension except t.
squaredboolFalseReturn the squared norm Σ f² instead. Default: False.

Returns

xarray.DataArray
The norm over the remaining dimensions, e.g. t.

Examples

>>> div_B.plasma.analysis.norm()

oscillation_frequencymethod#

def oscillation_frequency(window: tuple[float | None, float | None] = (None, None), method: str = 'zero_crossings', detrend: bool = True)

Measure the frequency of this oscillating time series from its zero crossings or peaks.

Parameters

NameTypeDefaultDescription
window(float or None, float or None)(None, None)The time interval (t0, t1) used; None for an open end. Default: every sample.
method('zero_crossings', 'peaks')"zero_crossings"Count the crossings of the mean (half a period apart), or the maxima (a period apart; for a signal that does not cross its mean, e.g. an energy, whose peaks are half the field’s period apart). Default: "zero_crossings".
detrendboolTrueSubtract the mean over the window first, so that crossings are of the mean. Default: True.

Returns

OscillationFit or None
omega, period and the times of the crossings or peaks used; None with fewer than two.

Examples

>>> probe.plasma.analysis.oscillation_frequency(window=(5.0, 40.0)).omega

parallel_wavenumbermethod#

def parallel_wavenumber(lines: xr.Dataset | None = None, method: str = 'fft', detrend: bool = True) -> xr.DataArray

Return the dominant parallel wavenumber of this field along field lines.

Parameters

NameTypeDefaultDescription
linesxarray.DatasetNoneTraced lines to sample this field along first. Default: this array already is the samples of sample_along(), over (s, line).
method('fft', 'crossings')"fft"How to estimate it. Default: "fft".
detrendboolTrueRemove the mean along each line first. Default: True.

Returns

xarray.DataArray
k_parallel over line and the other dimensions.

Examples

>>> phi.plasma.analysis.parallel_wavenumber(lines=lines)

polar_coordinatesmethod#

def polar_coordinates(center=(0.0, 0.0)) -> xr.DataArray

Return this array with coordinates r and theta in the X-Y plane.

Parameters

NameTypeDefaultDescription
center(float, float)(0.0, 0.0)The origin (X, Y) of the polar coordinates. Default: (0.0, 0.0).

Returns

xarray.DataArray
This array with the added coordinates.

Examples

>>> n.plasma.analysis.polar_coordinates(center=(0.0, 0.0))

project_modemethod#

def project_mode(dim: str, number: float, kind: str = 'sin', period: float = 1.0, bin_correction: bool = False) -> xr.DataArray

Return the amplitude of one Fourier mode along dim.

Parameters

NameTypeDefaultDescription
dimstrrequiredThe periodic dimension, e.g. "eta1".
numberfloatrequiredThe mode number, not a wavenumber: k = 2π number / L.
kind('sin', 'cos', 'complex')"sin""sin" (default) gives a of a sin(2π number x / period): 2 ⟨f sin(…)⟩; "cos" the cosine amplitude, and "complex" the complex amplitude 2 ⟨f exp(−i…)⟩ (abs() the amplitude, np.angle() the phase).
periodfloat1.0The period of dim. Default: 1, the logical unit interval.
bin_correctionboolFalseUndo the damping of binned particle data, whose bins average the mode over their width h: divide by sinc(number h / period). Default: False.

Returns

xarray.DataArray
The amplitude over the other dimensions.

Examples

>>> rho.plasma.analysis.project_mode(dim="eta2", number=3, kind="complex")

quasisymmetry_errormethod#

def quasisymmetry_error(helicity='QA', angles: str = 'boozer') -> xr.DataArray

Return the quasi-symmetry error of this |B| on each flux surface.

Parameters

NameTypeDefaultDescription
helicity('QA', 'QP', 'QH')"QA"The symmetry: a name, or (M, N) with N a full-torus toroidal mode number (its sign picks the handedness). Default: "QA".
angles('boozer', 'any')"boozer"As for boozer_spectrum().

Returns

xarray.DataArray
f_QS over the radius.

Examples

>>> boozer.mod_B.plasma.analysis.quasisymmetry_error(helicity="QH")

rational_surfacesmethod#

def rational_surfaces(count: int = 4, nfp: int | None = None, max_denominator: int = 12) -> xr.DataArray

Return where this rotational transform (or safety factor) profile is a low-order rational.

Parameters

NameTypeDefaultDescription
countint4The number of rational values. Default: 4.
nfpintNoneThe numerators are multiples of it. Default: the profile’s nfp attribute (GVEC’s, see plasma_plots.gvec.from_gvec()), else 1.
max_denominatorint12The largest m. Default: 12.

Returns

xarray.DataArray
The positions over surface, with the coordinates n, m and value.

Examples

>>> ev.iota.plasma.analysis.rational_surfaces(count=3)

reconnected_fluxmethod#

def reconnected_flux(relative: bool = True, o_point=None, x_point=None) -> xr.DataArray

Return the reconnected flux over time: this flux function between an O- and an X-point.

Parameters

NameTypeDefaultDescription
relativeboolTrueSubtract the value at the first time. Default: True.
o_point(float, float)NoneThe logical coordinates near which to look for the O-point. Default: the dominant island’s.
x_point(float, float)NoneThe same for the X-point.

Returns

xarray.DataArray
ΔΨ(t).

Examples

>>> A = B.plasma.analysis.flux_function()
>>> A.plasma.analysis.reconnected_flux().plasma.plot.timeseries(
... fit=(10.0, 30.0)
... )

relative_errormethod#

def relative_error(ref=None, skip_first: bool = True) -> xr.DataArray

Return the absolute relative deviation from ref or from this series’ first sample.

Parameters

NameTypeDefaultDescription
reffloat or array_like or xarray.DataArrayNoneThe reference, broadcast against data; must be non-zero everywhere. Default: data at the first time sample.
skip_firstboolTrueLeave out the first time sample (zero against the default reference). Default: True.

Returns

xarray.DataArray
The relative deviation over t.

Examples

>>> energy.plasma.analysis.relative_error(ref=exact_solution)

sample_alongmethod#

def sample_along(lines: xr.Dataset) -> xr.DataArray

Return this scalar field interpolated along traced field lines.

Parameters

NameTypeDescription
linesxarray.DatasetThe lines of [trace_field_lines()][trace_field_lines].

Returns

xarray.DataArray
The field over (s, line) after its other dimensions.

Examples

>>> along = phi.plasma.analysis.sample_along(lines)
>>> along.isel(line=0).plasma.plot.slice(x="s", y="t")

spatial_averagemethod#

def spatial_average(dims=None) -> xr.DataArray

Return the mean over the logical space dimensions eta1, eta2, eta3 (or dims).

For a binned e1_v1 distribution this is f(v1, t) averaged over space.

Parameters

NameTypeDefaultDescription
dimsstr or sequence of strNoneThe dimensions averaged over. Default: every logical dimension (eta1, eta2, eta3, or GVEC’s rho, theta, zeta) that data has.

Returns

xarray.DataArray
The mean over the remaining dimensions.

Examples

>>> distribution.plasma.analysis.spatial_average()

spectral_peaksmethod#

def spectral_peaks(n_peaks: int = 3, dims=None, omega_min: float = 1e-08, detrend=True, window=None) -> xr.Dataset

Return the strongest spectral peaks, with sub-bin frequencies.

Parameters

NameTypeDefaultDescription
n_peaksint3The number of peaks to return at most. Default: 3.
dimsstr or sequence of strNoneDimensions to sum the power over. Default: every dimension but omega. Only omega may remain.
omega_minfloat1e-08The lowest frequency a peak may have, which excludes DC. Default: 1e-8.
detrendbool or intTrueFor a time series: True subtracts the mean, False nothing, and an integer is the degree of a least-squares polynomial in t removed at every point first. An energy such as LinearMHD’s en_U oscillates at twice the wave frequency around a slow trend, so its peaks with detrend=2 sit at 2 * omega. Ignored for spectra. Default: True.
window(None, 'hann')NoneWindow applied before transforming a time series. Default: None.

Returns

xarray.Dataset
The peaks, strongest first.

Examples

>>> phi.plasma.analysis.spectral_peaks(n_peaks=2)

spectrogrammethod#

def spectrogram(length, step=None, detrend: bool = True, window: str | None = 'hann') -> xr.DataArray

Return power spectra in sliding time windows.

Parameters

NameTypeDefaultDescription
lengthint or floatrequiredThe window length: a sample count (integer, 4 to the number of samples) or a time span (float).
stepint or floatNoneThe shift between windows: a sample count (integer) or a time span (float). Default: a quarter of length.
detrendboolTrueSubtract each window’s mean. Default: True.
window('hann', None)"hann"The taper of each window, not compensated for. Default: "hann".

Returns

xarray.DataArray
The power over (t, omega, ...), t being each window’s center.

Examples

>>> signal.plasma.analysis.spectrogram(length=200.0, step=10.0)

surface_averagemethod#

def surface_average(jacobian=None, domain=None, quadrature=None) -> xr.DataArray

Return the flux-surface average of this field over its two angles.

Parameters

NameTypeDefaultDescription
jacobianxarray.DataArrayNone√g on the same grid, e.g. GVEC’s Jac (its absolute value is used). Default: from domain, else the numerical Jacobian of the X, Y, Z coordinates, which needs at least two radial points.
domainstruphy domainNoneThe mapping, for the exact √g of a Struphy run.
quadraturedictNoneExplicit weights for the angles, as for [volume_integral()][volume_integral].

Returns

xarray.DataArray
⟨f⟩ over the radius and every non-spatial dimension.

Examples

>>> ev.mod_B.plasma.analysis.surface_average(jacobian=ev.Jac)

time_fftmethod#

def time_fft(detrend: bool = False, window: str | None = None) -> xr.Dataset

Return the one-sided temporal coefficients and the power per bin.

Parameters

NameTypeDefaultDescription
detrendboolFalseSubtract the temporal mean first. Default: False.
window(None, 'hann')NoneMultiply by a periodic Hann window (see [hann()][hann]) first. Default: None (boxcar).

Returns

xarray.Dataset
coefficients and power over omega and the other dimensions.

Examples

>>> phi.plasma.analysis.time_fft(detrend=True)

toroidal_componentsmethod#

def toroidal_components(R0: float, Z0: float = 0.0) -> xr.DataArray

Return the Cartesian components rotated to (radial, poloidal, toroidal) about an axis at R0.

Parameters

NameTypeDefaultDescription
R0floatrequiredThe major radius of the magnetic axis.
Z0float0.0The height of the magnetic axis. Default: 0.

Returns

xarray.DataArray
The vector field in toroidal components.

Examples

>>> u.plasma.analysis.toroidal_components(R0=3.0)

trace_branchmethod#

def trace_branch(theory, *, window: float = 0.2, k_range=None, threshold: float = 0.001) -> xr.Dataset

Return the measured frequency of a dispersion branch near theory(k) in this (omega, k) spectrum.

Parameters

NameTypeDefaultDescription
theorycallablerequiredThe expected branch omega(k), applied to an array of k; of a complex frequency (as plasma_plots.theory returns), the real part is used.
windowfloat0.2The relative half-width of the search window about the theory. Default: 0.2.
k_range(float, float)NoneThe k interval to trace (negative k are never traced). Default: every k >= 0.
thresholdfloat0.001Maxima weaker than this times the strongest one found count as no wave. Default: 1e-3.

Returns

xarray.Dataset
The measured branch over k.

Examples

>>> spectrum.plasma.analysis.trace_branch(
... bohm_gross, window=0.2, k_range=(1.5, 5.5)
... )

velocity_momentsmethod#

def velocity_moments(dims=None) -> xr.Dataset

Return density, mean velocity and variance of a binned distribution over its velocity dimensions.

See plasma_plots.analysis.velocity_moments() for the definitions.

Parameters

NameTypeDefaultDescription
dimsstr or sequence of strNoneThe velocity dimensions integrated over, each with a coordinate of at least two bins. Default: every one of v1, v2, v3 that f has.

Returns

xarray.Dataset
The moments, over the remaining dimensions.

Examples

>>> distribution.plasma.analysis.velocity_moments()

ArrayDataclass#

class ArrayData(_ArrayAccessor)

Bases: _ArrayAccessor

The data behind each plot in ArrayPlots, without rendering it.

Every method here mirrors one on array.plasma.plot and returns the plain, already selected xarray object (or a small tuple/dict of them) that method would have drawn — useful to hand to a different plotting library (Plotly, bokeh, …), or to inspect directly.

Examples

>>> phi.plasma.data.slice(x="eta1", y="eta2", t=-1)
>>> n.plasma.data.lineout(x="eta1", t=-1, eta2=0.3, eta3=0)

comparemethod#

def compare(other: xr.DataArray, *, mode: Literal['difference', 'ratio'] = 'difference') -> xr.DataArray

Return the aligned difference or ratio ArrayPlots.compare() would plot.

Parameters

NameTypeDefaultDescription
otherxarray.DataArrayrequiredThe array to compare with, e.g. a reference run; aligned with this one first.
mode('difference', 'ratio')"difference"first - second, or first / second (NaN where second is zero). Default: "difference".

Returns

xarray.DataArray
This array minus other, or divided by it, after alignment.

Examples

>>> field.plasma.data.compare(reference_field, mode="ratio")

critical_pointsmethod#

def critical_points(refine: bool = True, **selection) -> xr.Dataset

Return the O- and X-points ArrayPlots.critical_points() would mark.

Parameters

NameTypeDefaultDescription
refineboolTrueLocate the zero within the cell by Newton’s method (the cell’s centre otherwise). Default: True.
**selection{}The other dimensions, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

xarray.Dataset
The points over point (and the dimensions left, e.g. t).

Examples

>>> A.plasma.data.critical_points(t=-1)

dispersionmethod#

def dispersion(dim: str | None = None, detrend: bool = True) -> xr.DataArray

Return the space-time power spectrum ArrayPlots.dispersion() would plot.

The same as ArrayAnalysis.dispersion(); included here too for parity with every other plot.

Parameters

NameTypeDefaultDescription
dimstrNoneThe spatial dimension. Default: the sole dimension other than t.
detrendboolTrueRemove the time-mean at each point of dim first, which otherwise dominates the spectrum as a spurious zero-frequency line. Default: True.

Returns

xarray.DataArray
The power over angular frequency omega and wavenumber.

Examples

>>> field.plasma.data.dispersion(dim="eta1")

gridmethod#

def grid(name: str | None = None, **selection)

Return this field as a pyvista.StructuredGrid on its physical points.

Every dimension but eta1, eta2, eta3 (and component) is selected first. This is the data behind every 3-D view, ready for any PyVista filter.

Parameters

NameTypeDefaultDescription
namestrNoneThe name of the point data. Default: the field’s label.
**selection{}Every dimension but eta1, eta2, eta3 and component, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

pyvista.StructuredGrid
The grid, with the field as its point data.

Examples

>>> grid = phi.plasma.data.grid(t=-1)

lineoutmethod#

def lineout(x: str | None = None, **selection) -> xr.DataArray

Return the 1-D profile ArrayPlots.lineout() would plot.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension to keep: checked to be the only one left after selection. Default: whichever it is.
**selection{}The other dimensions: an integer is a position (t=-1 the last), a float the nearest coordinate value.

Returns

xarray.DataArray
The selected profile, over x only.

Raises

ValueError
If more or fewer than one dimension remains, or x is not the remaining one.

Examples

>>> n.plasma.data.lineout(x="eta1", t=-1, eta2=0.3, eta3=0)

overlay_orbitsmethod#

def overlay_orbits(orbits: xr.Dataset, *, x: str, y: str, max_markers: int = 200, **selection) -> tuple[xr.DataArray, xr.Dataset]

Return the field slice and marker subset ArrayPlots.overlay_orbits() would plot.

Parameters

NameTypeDefaultDescription
orbitsxarray.DatasetrequiredAn orbits product with position variables named after view.x and view.y (e.g. its logical coordinates, to overlay directly on a logical-coordinates slice).
xstrrequiredThe horizontal dimension of the slice. orbits must have a position variable of the same name (e.g. logical eta1, to overlay directly on a logical-coordinates slice of this field).
ystrrequiredThe vertical dimension of the slice; orbits needs a variable of this name too.
max_markersint200Draw only the first max_markers markers. Default: 200.
**selection{}Every other dimension of this field, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

tuple of (xarray.DataArray, xarray.Dataset)
The field slice, and the orbits of the first max_markers markers.

Raises

ValueError
If orbits has no variables named x and y, or no marker dimension.

Examples

>>> field, paths = field.plasma.data.overlay_orbits(
... orbits, x="eta1", y="eta2", t=-1
... )

poincaremethod#

def poincare(seeds=8, turns: float | None = None, section: float | None = None, **selection) -> xr.Dataset

Return the Poincaré section ArrayPlots.poincare() would plot.

Parameters

NameTypeDefaultDescription
seeds(int, dict, array_like or xarray.Dataset)8Where the lines start; see plasma_plots.fieldlines.trace_field_lines(). Default: 8 along the radius.
turnsfloatNoneHow many toroidal transits to trace. Default: 20.
sectionfloatNoneThe toroidal logical coordinate of the plane. Default: the first grid value.
**selection{}The other dimensions, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

xarray.Dataset
The punctures over (puncture, line); see plasma_plots.fieldlines.poincare_section().

Examples

>>> B.plasma.data.poincare(seeds=12, turns=100, t=-1)

slicemethod#

def slice(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', **selection) -> xr.DataArray

Return the single 2-D slice ArrayPlots.slice() would plot.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

xarray.DataArray
The selected slice.

Examples

>>> phi.plasma.data.slice(x="eta1", y="eta2", t=-1)
>>> n.plasma.data.slice(coords="physical", plane="XY", t=-1, eta3=0)

slices_3dmethod#

def slices_3d(cuts: dict | None = None, **selection) -> list[xr.DataArray]

Return the logical cuts ArrayPlots.slices_3d() would draw.

Parameters

NameTypeDefaultDescription
cutsdictNone{dim: position or list of positions} along eta1, eta2, eta3: a float is the nearest logical coordinate, an integer a grid index (-1 the last). Default: the middle of every dimension, or the whole plane of a 2-D field.
**selection{}Every dimension but eta1, eta2, eta3, e.g. t=0: an integer is a position, a float the nearest coordinate value.

Returns

list of xarray.DataArray
One array per cut.

timeseriesmethod#

def timeseries(*others) -> list[xr.DataArray]

Return this time series and any others, validated, as ArrayPlots.timeseries() plots them.

Parameters

NameDefaultDescription
*others()Further arrays with the single dimension t; they may come from other runs and need not share this array’s time grid.

Returns

list of xarray.DataArray
This series first, then others.

Raises

ValueError
If a series does not have the dimension t.

Examples

>>> energy.plasma.data.timeseries(other_run_energy)

to_vtkmethod#

def to_vtk(path, *, name: str | None = None, **selection) -> list[str]

Write this field to VTK structured-grid files for ParaView.

One .vts per time and a .pvd collection, or a single .vts without t. Select other dimensions first.

Parameters

NameTypeDefaultDescription
pathstr or pathlib.PathrequiredThe .vts file (the suffix is set to .vts), or with a t dimension the directory to write into (created if needed).
namestrNoneThe name of the point data, also the file stem in a time series. Default: the field’s label.
**selection{}Every dimension but t, eta1, eta2, eta3 and component: an integer is a position, a float the nearest coordinate value. t is kept unless selected too.

Returns

list of str
The paths of the written files.

Examples

>>> field.plasma.data.to_vtk("frames")

trajectoriesmethod#

def trajectories(max_markers: int = 200) -> xr.Dataset

Return the marker-position subset ArrayPlots.trajectories() would plot.

Parameters

NameTypeDefaultDescription
max_markersint200Draw only the first max_markers markers. Default: 200.

Returns

xarray.Dataset
The orbits of the first max_markers markers.

Raises

ValueError
If the orbits lack x, y or z, or a marker dimension.

vectormethod#

def vector(x: str, y: str, components: tuple[int, int] = (0, 1), stride: int = 1, coordinates: Coordinates = 'logical', **selection) -> xr.DataArray

Return the selected, strided vector field ArrayPlots.vector() would plot.

Parameters

NameTypeDefaultDescription
xstrrequiredThe dimension along the horizontal axis.
ystrrequiredThe dimension along the vertical axis.
components(int, int)(0, 1)The positions along component_dim of the two components drawn. Default: (0, 1).
strideint1Draw every stride-th arrow along x and y. Default: 1.
coordinates('logical', 'physical')"logical"Place the arrows at the logical coordinates, or at the attached physical X, Y, Z (then x and y must be two of eta1, eta2, eta3, and the axes have equal scales). Default: "logical".
**selection{}Every dimension but x, y and the component dimension, e.g. t=-1, eta3=0: an integer is a position, a float the nearest coordinate value.

Returns

xarray.DataArray
The two selected components over x and y, every stride-th point.

viewmethod#

def view(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', **selection) -> xr.DataArray

Return every remaining dimension of this array, sweep included.

This data is shared by ArrayPlots.panels(), .viewer(), .animation() and .frames(), which each render one frame of exactly this data at a time.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

xarray.DataArray
The selection ordered (sweep, x, y). With coords="physical" the periodic seam of a cell-centered grid is closed, as in every drawn frame (one more point along a periodic angle).

Raises

ValueError
If other dimensions than sweep, x and y remain, or the physical coordinates are missing.

Examples

>>> n.plasma.data.view(coords="physical", plane="XY", eta3=0)

volume_slicesmethod#

def volume_slices(indices: dict[str, int] | None = None, **selection) -> dict[str, xr.DataArray]

Return the three orthogonal planes ArrayPlots.volume_slices() would plot.

Parameters

NameTypeDefaultDescription
indicesdict of str to intNoneThe index at which each dimension is held fixed, e.g. {"eta3": 0}. Default: the middle index of every dimension.
**selection{}Every dimension but the three of the volume, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

dict of str to xarray.DataArray
The three planes.

ArrayPlotsclass#

class ArrayPlots(_ArrayAccessor)

Bases: _ArrayAccessor

Plots of one array, as array.plasma.plot.<kind>(...).

Dimensions that are neither displayed nor swept are selected by naming them: an integer is a position (t=0 the first, t=-1 the last), and a float is the nearest coordinate value (t=0.35). Selecting a name that is not a dimension of the array, or a string or bool value, raises TypeError.

Examples

>>> phi.plasma.plot.slice(x="eta1", y="eta2", t=-1)
>>> phi.plasma.plot.lineout(x="eta1", t=-1, eta2=0.5, eta3=0)

against_theorymethod#

def against_theory(theory=None, *, show_error: bool = True, xlabel=None, ylabel=None, title=None, logx: bool = False, logy: bool = False, backend: Backend | None = None)

Plot these measured values as points against a theory function.

The array is 1-D, over a parameter (e.g. the wavenumber); the relative error is shown too.

Parameters

NameTypeDefaultDescription
theorycallable, (x, y) pair or dictNoneA function of the parameter, an (x, y) pair, or a dict of labels to these, drawn as lines over the measured range. Complex values (e.g. from plasma_plots.theory) are compared by their real part; for growth or damping rates pass lambda k: f(k).imag.
show_errorboolTrueAdd a second panel with (measured - theory) / theory against the first theory, for every measured series. A theory given as points is interpolated linearly between them (NaN outside them). Default: True.
xlabelstrNoneThe horizontal axis label. Default: the coordinate label of the first measured array.
ylabelstrNoneThe value axis label. Default: the value label of the first measured array.
titlestrNoneThe title. Default: "Measured against theory".
logxboolFalseUse a logarithmic parameter axis. Default: False.
logyboolFalseUse a logarithmic value axis. Default: False.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes (with show_error, the upper one) and the drawn artists.

Examples

>>> traced = spectrum.plasma.analysis.trace_branch(
... bohm_gross, k_range=(1.5, 5.5)
... )
>>> traced.omega.plasma.plot.against_theory(bohm_gross)

along_field_linesmethod#

def along_field_lines(lines: xr.Dataset, *, k_parallel: bool = False, method: str = 'fft', max_lines: int = 12, ax=None, title: str | None = None, backend: Backend | None = None, **selection)

Plot this scalar field along traced field lines, one curve per line.

Parameters

NameTypeDefaultDescription
linesxarray.DatasetrequiredThe lines of ArrayAnalysis.field_lines().
k_parallelboolFalseEstimate each line’s parallel wavenumber (see parallel_wavenumber()) and put it in the legend. Default: False.
method('fft', 'crossings')"fft"The estimate’s method. Default: "fft".
max_linesint12Draw only the first max_lines lines. Default: 12.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: the samples’ label.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The other dimensions, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the lines; with k_parallel, data["k_parallel"].

Examples

>>> phi.plasma.plot.along_field_lines(lines, k_parallel=True, t=-1)

animationmethod#

def animation(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', vmin=None, vmax=None, shared_clim: bool = True, cmap: str | None = None, equal_aspect: bool | None = None, title: str | None = None, symmetric: bool = False, robust: bool = False, levels=None, fill: bool = True, overlays: dict | None = None, xlabel: str | None = None, ylabel: str | None = None, colorbar_label: str | None = None, interval: int = 100, step: int = 1, max_frames: int | None = None, alongside=None, backend: Backend | None = None, **selection)

Animate the sweep; keep a reference to the returned Matplotlib animation.

The same as plot.view(...).animation(...); see view() for the shared options.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
vminfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
vmaxfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
shared_climboolTrueFix the color limits over all selected data, including frames omitted by a panel layout or export step; False rescales each frame. Default: True.
cmapstrNoneThe colormap. Default: the Struphy style’s.
equal_aspectboolNoneEqual axis scales. Default: True for physical coordinates, else False.
titlestrNoneThe title. Default: the array’s label.
symmetricboolFalseCenter the color limits on zero, for perturbations with a diverging cmap. Default: False.
robustboolFalseTake the color limits from the 1st/99th percentiles, so a few outliers do not wash out the rest. Default: False.
levelsint or sequence of floatNoneContour lines of the field on top, e.g. an interface or flux surfaces: a number of evenly spaced levels, or explicit values. Default: none.
fillboolTrueDraw the colored field; with False only the levels lines are drawn, colored by cmap. Default: True.
overlaysdictNoneFurther elements on top: contours_of (a second field whose contour lines are drawn, e.g. the flux function over the current; with contour_levels, contour_color), boundary=True (the grid’s outline), grid_lines=n (every n-th grid line), lines (label to (x, y) or a function y(x), e.g. characteristics on a space-time map) and points (label to (x, y)), in line_color and point_color (white by default, for dark colormaps).
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s name and units.
ylabelstrNoneThe vertical axis label. Default: the coordinate’s name and units.
colorbar_labelstrNoneThe color bar label. Default: the array’s label and units.
intervalint100The delay between frames, in milliseconds. Default: 100.
stepint1Show every step-th element of the sweep. Default: 1.
max_framesintNoneKeep at most this many frames, evenly spaced over those step leaves (the first and last included), e.g. to keep a Plotly animation small. Default: all.
alongsidelist of xarray.DataArrayNoneFurther arrays with the same dimensions (e.g. the density next to the vorticity), animated side by side in sync, each with its own color limits and the same selection and options.
backend('matplotlib', 'plotly')"matplotlib"Draw with Matplotlib, or as an interactive Plotly figure with a slider (in result.fig; needs plotly, see plasma_plots.plotly_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

matplotlib.animation.FuncAnimation or PlotResult
The animation; with backend="plotly" a result whose Plotly figure has a slider and Play/Pause buttons.

Examples

>>> n.plasma.plot.animation(
... coords="physical", plane="XY", eta3=0, levels=[0.2]
... )
>>> vorticity.plasma.plot.animation(alongside=[density], eta3=0)

boozer_spectrummethod#

def boozer_spectrum(top: int = 8, helicity=None, log: bool = True, angles: str = 'boozer', x_of=None, xlabel: str | None = None, title: str | None = None, backend: Backend | None = None, **selection)

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

Parameters

NameTypeDefaultDescription
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.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Other dimensions to select first: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the lines; data holds the amplitudes and the error.

Examples

>>> boozer.mod_B.plasma.plot.boozer_spectrum(top=8, helicity="QA")

comparemethod#

def compare(other: xr.DataArray, *, mode: Literal['difference', 'ratio'] = 'difference', ax=None, backend: Backend | None = None)

Plot a one-dimensional aligned difference or ratio against another array.

Parameters

NameTypeDefaultDescription
otherxarray.DataArrayrequiredThe array to compare with, e.g. a reference run; aligned with this one first.
mode('difference', 'ratio')"difference"first - second, or first / second (NaN where second is zero). Default: "difference".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn line.

Examples

>>> field.plasma.plot.compare(reference_field, mode="ratio")

convergencemethod#

def convergence(*others, order: float | None = None, xlabel: str | None = None, title: str = 'Convergence', ax=None, backend: Backend | None = None)

Plot these errors against their resolution (or step size) on log-log axes, with the order.

The array is 1-D over the resolution, e.g. an error norm per number of cells; each series gets its fitted convergence order (or, with order, a reference slope).

Parameters

NameTypeDefaultDescription
*others()Further 1-D error arrays, e.g. of other methods or norms, drawn in the same axes.
orderfloatNoneWith None (default), fits and draws the observed order via plasma_plots.analysis.convergence_order(). Pass an explicit order (e.g. 2 for second-order) to draw a reference slope through the first point instead of fitting one.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s label.
titlestr'Convergence'The axes title. Default: "Convergence".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and, per series, the error line and its fitted or reference line.

Raises

ValueError
If an array is not one-dimensional.

Examples

>>> errors = xr.DataArray(
... l2_errors, dims="n", coords={"n": [16, 32, 64, 128]}, name="L2 error"
... )
>>> errors.plasma.plot.convergence(max_errors, backend="plotly")

critical_pointsmethod#

def critical_points(x: str | None = None, y: str | None = None, coords: Coordinates = 'logical', plane: Plane = 'XY', levels=14, cmap=None, label_values: bool = False, ax=None, backend: Backend | None = None, **selection)

Plot the contours of this flux function with its O-points and X-points.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis. Default: the first of the plane.
ystrNoneThe dimension along the vertical axis. Default: the second of the plane.
coords('logical', 'physical')"logical"Logical coordinates, or the physical plane. Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ')"XY"The physical plane. Default: "XY".
levelsint or sequence of float14Contour lines of the flux, as for [plot_slice()][plot_slice]. Default: 14.
cmapstr or matplotlib.colors.ColormapNoneThe colormap. Default: "RdBu_r".
label_valuesboolFalseWrite the flux value next to each point. Default: False.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The other dimensions, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes, the mesh, the contours and the scatters; data["points"] holds the points.

Examples

>>> A = B.plasma.analysis.flux_function()
>>> A.plasma.plot.critical_points(t=-1, eta3=0)
>>> A.plasma.plot.critical_points(coords="physical", t=-1, eta3=0)

cross_spectrummethod#

def cross_spectrum(other: xr.DataArray, *, dims=None, detrend: bool = True, window=None, omega_max=None, backend: Backend | None = None)

Plot the magnitude, coherence and phase of other relative to this signal.

The coherence is shown only with dims.

Parameters

NameTypeDefaultDescription
otherxarray.DataArrayrequiredThe second signal, on the same time grid; its phase is relative to this one.
dimsstr or sequence of strNoneDimensions to sum the cross-spectrum over, as an ensemble. Default: none (no coherence).
detrendboolTrueSubtract each signal’s temporal mean first. Default: True.
window(None, 'hann')NoneWindow applied to both signals before transforming. Default: None.
omega_maxfloatNoneThe largest angular frequency shown. Default: all.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn artists; data holds "peak_omega" and "peak_phase_deg".

Examples

>>> u.plasma.plot.cross_spectrum(b, dims="eta3", omega_max=1.5)

dispersionmethod#

def dispersion(dim: str | None = None, detrend: bool = True, branches: dict | None = None, log: bool = True, dynamic_range: float = 6.0, kmin: float | None = None, kmax: float | None = None, omega_max: float | None = None, vmin: float | None = None, vmax: float | None = None, cmap=None, ax=None, title: str | None = None, frequencies: dict | None = None, points: dict | None = None, fits=(), backend: Backend | None = None)

Plot the space-time power spectrum of this (t, dim) field as a dispersion relation.

branches optionally overlays named theoretical curves (a mapping of label to a callable omega(k), or an explicit (k, omega) pair), to compare against, e.g. {"Bohm-Gross": lambda k: np.sqrt(1 + 3 * k**2)}. frequencies draws labeled horizontal lines (cutoffs), points measured points ((k, omega) pairs or plasma_plots.spectral.trace_branch() results).

Parameters

NameTypeDefaultDescription
dimstrNoneThe spatial dimension to transform. Default: the one besides t (see plasma_plots.analysis.power_spectrum()).
detrendboolTrueRemove the time-mean at each point of dim first, which otherwise dominates the spectrum as a spurious zero-frequency line. Default: True.
branchesdict or callableNoneTheoretical curves to compare against, drawn dashed: a dict of labels to a callable omega(k) or an explicit (k, omega) pair of arrays; or one callable that returns a dict of branch names to frequencies, such as the dispersion relations of plasma_plots.theory or Struphy’s struphy.dispersion_relations objects (a callable in the dict may return such a dict too). Complex frequencies are drawn by their real part.
logboolTrueColor by log10 of the power. Default: True.
dynamic_rangefloat6.0With log, the number of decades below the peak that the default color limits cover. Default: 6.0.
kminfloatNoneShow only k >= kmin, e.g. 0 for the positive quadrant. Default: all k.
kmaxfloatNoneShow only |k| <= kmax. Default: all k.
omega_maxfloatNoneShow only ω <= omega_max. Default: all non-negative ω.
vminfloatNoneThe lower color limit (in log10 of the power with log). Default: the peak minus dynamic_range with log, else the minimum.
vmaxfloatNoneThe upper color limit (in log10 of the power with log). Default: the peak.
cmapstr or matplotlib.colors.ColormapNoneThe colormap. Default: Matplotlib’s default.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: "Dispersion relation of <label>".
frequenciesdict of str to floatNoneLabeled horizontal lines, e.g. cutoffs or resonances.
pointsdictNoneMeasured points to mark: a dict of labels to a (k, omega) pair or a trace_branch() result (an xarray.Dataset with k and omega).
fitssequence of BranchFit()Fitted straight branches from fit_dispersion_branches(), drawn dotted as omega = velocity * k over the shown k >= 0. Default: none.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn artists.

Examples

>>> E.plasma.plot.dispersion(
... dim="eta1", branches={"Bohm-Gross": lambda k: np.sqrt(1 + 3 * k**2)}
... )
>>> # or pass the spectrum itself
>>> spectrum = E.plasma.analysis.dispersion(dim="eta1")
>>> fits = spectrum.plasma.analysis.fit_branches(n_branches=1)
>>> spectrum.plasma.plot.dispersion(
... kmin=0, fits=fits, dynamic_range=15, backend="plotly"
... )

filteredmethod#

def filtered(result, *, ax=None, backend: Backend | None = None, **selection)

Plot a probe of this signal against a filtered reconstruction.

result is a ArrayAnalysis.filter_time() result or a filtered array; the probe is selected by keyword.

Parameters

NameTypeDefaultDescription
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.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**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 raw and the filtered line.

Examples

>>> band = phi.plasma.analysis.filter_time(dims=("eta1", "eta2", "eta3"))
>>> phi.plasma.plot.filtered(band, eta1=0.4, eta2=0.0, eta3=0.0)

framesmethod#

def frames(directory, *, x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', vmin=None, vmax=None, shared_clim: bool = True, cmap: str | None = None, equal_aspect: bool | None = None, title: str | None = None, symmetric: bool = False, robust: bool = False, levels=None, fill: bool = True, overlays: dict | None = None, xlabel: str | None = None, ylabel: str | None = None, colorbar_label: str | None = None, step: int = 1, prefix: str = 'frame', dpi: int = 110, **selection)

Export the sweep as PNG frames.

Equivalent to plot.view(...).save_frames(directory); see view() for the shared options.

Parameters

NameTypeDefaultDescription
directorystr or pathlib.PathrequiredThe directory to write into; created if needed.
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
vminfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
vmaxfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
shared_climboolTrueFix the color limits over all selected data, including frames omitted by a panel layout or export step; False rescales each frame. Default: True.
cmapstrNoneThe colormap. Default: the Struphy style’s.
equal_aspectboolNoneEqual axis scales. Default: True for physical coordinates, else False.
titlestrNoneThe title. Default: the array’s label.
symmetricboolFalseCenter the color limits on zero, for perturbations with a diverging cmap. Default: False.
robustboolFalseTake the color limits from the 1st/99th percentiles, so a few outliers do not wash out the rest. Default: False.
levelsint or sequence of floatNoneContour lines of the field on top, e.g. an interface or flux surfaces: a number of evenly spaced levels, or explicit values. Default: none.
fillboolTrueDraw the colored field; with False only the levels lines are drawn, colored by cmap. Default: True.
overlaysdictNoneFurther elements on top: contours_of (a second field whose contour lines are drawn, e.g. the flux function over the current; with contour_levels, contour_color), boundary=True (the grid’s outline), grid_lines=n (every n-th grid line), lines (label to (x, y) or a function y(x), e.g. characteristics on a space-time map) and points (label to (x, y)), in line_color and point_color (white by default, for dark colormaps).
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s name and units.
ylabelstrNoneThe vertical axis label. Default: the coordinate’s name and units.
colorbar_labelstrNoneThe color bar label. Default: the array’s label and units.
stepint1Export every step-th element of the sweep. Default: 1.
prefixstr'frame'The file names are <prefix>_0000.png, <prefix>_0001.png, … Default: "frame".
dpiint110The resolution of the images. Default: 110.
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

list of str
The paths of the written files.

Examples

>>> phi.plasma.plot.frames("frames", x="eta1", y="eta2", eta3=0, step=5)

glyphsmethod#

def glyphs(components: Literal['cartesian', 'contravariant'] = 'cartesian', stride: int = 2, scale: float | None = None, cmap='viridis', show_domain: bool = True, title: str | None = None, plotter=None, **selection)

Draw PyVista arrows of this (component, eta1, eta2, eta3) vector field.

The arrows are colored by magnitude.

Parameters

NameTypeDefaultDescription
components('cartesian', 'contravariant')"cartesian"How to read the components: Cartesian x/y/z, or contravariant logical components, pushed forward. Default: "cartesian".
strideint2Draw an arrow at every stride-th point in every direction. Default: 2.
scalefloatNoneArrow length of the largest vector, in physical units. Default: a tenth of the domain size.
cmapstr or matplotlib colormap'viridis'The colormap of the magnitude. Default: "viridis".
show_domainboolTrueDraw the domain’s outer surface translucently for context. Default: True.
titlestrNoneText in the scene’s corner. Default: the field’s label; "" for none.
plotterpyvista.PlotterNoneDraw into this scene instead of a new one, to combine several views. The camera is only aimed at the field when this function creates the plotter.
**selection{}Every dimension but component, eta1, eta2, eta3, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

pyvista.Plotter
The plotter with the arrows, not yet shown.

Examples

>>> B.plasma.plot.glyphs(stride=3, t=-1).show()

isosurfacemethod#

def isosurface(values=5, cmap='viridis', opacity: float = 1.0, clim=None, show_domain: bool = True, title: str | None = None, symmetric: bool = False, robust: bool = False, plotter=None, **selection)

Draw PyVista contour surfaces of this scalar field in physical space.

For a 2-D field, contour lines over the colored plane instead.

Parameters

NameTypeDefaultDescription
valuesint or list of float5The number of evenly spaced levels strictly between the color limits, or explicit levels. Default: 5.
cmapstr or matplotlib colormap'viridis'The colormap. Default: "viridis".
opacityfloat1.0Opacity of the surfaces (of the plane for a 2-D field). Default: 1.
clim(float, float)NoneColor limits; default from the field’s values, see symmetric and robust.
show_domainboolTrueDraw the domain’s outer surface translucently for context (3-D fields only). Default: True.
titlestrNoneText in the scene’s corner. Default: the field’s label; "" for none.
symmetricboolFalseColor limits symmetric about zero. Default: False.
robustboolFalseColor limits from percentiles instead of the extremes, so outliers don’t wash out the colors. Default: False.
plotterpyvista.PlotterNoneDraw into this scene instead of a new one, to combine several views. The camera is only aimed at the field when this function creates the plotter.
**selection{}Every dimension but eta1, eta2, eta3, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

pyvista.Plotter
The plotter with the surfaces, not yet shown.

Examples

>>> phi.plasma.plot.isosurface(values=[-0.5, 0.5], cmap="RdBu_r", t=0).show()

line_animationmethod#

def line_animation(x: str | None = None, sweep: str = 't', reference=None, x_of=None, xlabel: str | None = None, ylim=None, step: int = 1, max_frames: int | None = None, interval: int = 100, title: str | None = None, alongside=None, alongside_logy: bool = False, backend: Backend | None = None, **selection)

Animate a one-dimensional profile over sweep.

Optionally with the exact profile of each frame (reference=lambda x, t: ...). Keep a reference to the returned animation, or it stops.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis. Default: the one besides sweep.
sweepstr't'The dimension to animate over. Default: "t".
referencecallable, (x, y) pair or dictNoneThe exact profile of each frame, drawn dashed in black: a function of the plotted x and of the sweep value (lambda x, t: ...; a function of x alone is fixed), an (x, y) pair, a 1-D xarray.DataArray (drawn over its own coordinate), or a dict of labels to these.
x_ofcallableNoneMaps the x coordinate to the plotted axis, e.g. lambda eta1: L * eta1.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s label, or "x" with x_of.
ylim(float, float)NoneThe fixed value axis limits. Default: the range of the data and references, padded by 5 %.
stepint1Use every step-th value of the sweep. Default: 1.
max_framesintNoneKeep at most this many frames, evenly spaced over those step leaves (the first and last included), e.g. to keep a Plotly animation small. Default: all.
intervalint100The delay between frames, in milliseconds. Default: 100.
titlestrNoneThe title, followed in each frame by the sweep value. Default: the array’s label.
alongsidesequenceNoneOne panel below the profile per item, in sync with it: an array over sweep and one other dimension (another profile, animated, e.g. the density next to the velocity), or an array over sweep alone, or a list of those (time series such as energies, drawn whole with a marker at each frame’s value of the sweep, nearest where the times differ). Default: none.
alongside_logyboolFalseLogarithmic value axes for the time-series panels. Default: False.
backend('matplotlib', 'plotly')"matplotlib"Draw with Matplotlib, or as an interactive Plotly figure with a slider (in result.fig; needs plotly, see plasma_plots.plotly_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but x and sweep: an integer is a position (eta2=0), a float the nearest coordinate value.

Returns

matplotlib.animation.FuncAnimation or PlotResult
The animation, one frame per step along sweep; with backend="plotly" a result whose Plotly figure has a slider and Play/Pause buttons.

Examples

>>> T.plasma.plot.line_animation(reference={"exact": exact}, step=2)
>>> u.plasma.plot.line_animation(
... x="eta1",
... alongside=[n, [en_U, en_B]],
... alongside_logy=True,
... eta2=0,
... eta3=0,
... )

lineoutmethod#

def lineout(x: str | None = None, ax=None, title: str | None = None, reference=None, x_of=None, xlabel: str | None = None, rationals: int | None = None, nfp: int | None = None, backend: Backend | None = None, **selection)

Plot a one-dimensional profile after selecting every other dimension.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension to keep. Default: the only one left after selection.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: the array’s label.
referencecallable, array, (x, y) pair or dictNoneExact or expected profiles, drawn dashed: a function of the plotted x (or of x and t, taking the profile’s time), a 1-D xarray.DataArray (drawn over its own coordinate), an (x, y) pair, or a dict of labels to these.
x_ofcallableNoneMaps the coordinate to the plotted axis, e.g. lambda eta1: L * eta1.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s label.
rationalsintNoneMark where a rotational transform (or safety factor) profile takes its rationals lowest-order rational values n/m: a dotted line at each value, labeled, and a point at each crossing (see plasma_plots.analysis.rational_surfaces()). Default: none.
nfpintNoneWith rationals: the numerators n are multiples of it. Default: the profile’s nfp attribute, else 1.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The other dimensions: an integer is a position (t=-1 the last), a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the drawn lines.

Examples

>>> phi.plasma.plot.lineout(x="eta1", t=-1, eta2=0.5, eta3=0)
>>> T.plasma.plot.lineout(
... x="eta1", t=-1, reference=exact, x_of=lambda eta1: L * eta1
... )
>>> # GVEC's ι(ρ) and its rational surfaces
>>> ev.iota.plasma.plot.lineout(rationals=4)

mode_amplitudesmethod#

def mode_amplitudes(dims=None, names=('m', 'n'), top: int = 6, fit=None, reduce: str = 'max', scale=None, relative: bool = False, logy: bool = True, ax=None, backend: Backend | None = None, **selection)

Plot the amplitude of the strongest (m, n) modes of this field over time.

Each mode is reduced over the remaining dimensions (e.g. radius) by reduce, with optional growth fits (fit=(t0, t1) or True).

Parameters

NameTypeDefaultDescription
dimssequence of strNoneThe periodic dimensions to decompose. Default: the two logical angles, ("eta2", "eta3") or GVEC’s (see plasma_plots.spectral.mode_spectrum()).
namessequence of str('m', 'n')The names of the mode numbers along dims. Default: ("m", "n").
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.
reduce('max', 'mean')"max"How each mode is reduced over the remaining dimensions. Default: "max".
scaleint or sequence of intNoneMultiplies the mode numbers, e.g. (1, 6) for full-torus n of a sixth of a torus. Default: 1, or nfp along GVEC’s toroidal angle (see plasma_plots.spectral.mode_spectrum()).
relativeboolFalseShow each mode relative to the mean (the zero mode). Default: False.
logyboolTrueLogarithmic amplitude axis. Default: True.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Dimensions other than t to select first: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes, the drawn lines, the fits in fit_results and the plotted data["amplitudes"].

Examples

>>> phi.plasma.plot.mode_amplitudes(top=2, fit=(100, 500))

mode_mapmethod#

def mode_map(dims=None, m_range=None, n_range=None, reduce: str = 'max', scale=None, log: bool = True, ax=None, backend: Backend | None = None, **selection)

Plot |amplitude| over the (m, n) plane at one time.

The time is selected by keyword (e.g. t=-1); the amplitude is reduced over the remaining dimensions by reduce.

Parameters

NameTypeDefaultDescription
dimssequence of strNoneThe two periodic dimensions to decompose. Default: the two logical angles, ("eta2", "eta3") or GVEC’s (see plasma_plots.spectral.mode_spectrum()).
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.
reduce('max', 'mean')"max"How the amplitude is reduced over the remaining dimensions. Default: "max".
scaleint or sequence of intNoneMultiplies the mode numbers, e.g. (1, 6) for full-torus n of a sixth of a torus. Default: 1, or nfp along GVEC’s toroidal angle (see plasma_plots.spectral.mode_spectrum()).
logboolTrueColor by log10(|amplitude|), clipped at 4 decades below the maximum. Default: True.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The time and any other dimensions to select first, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes, the mesh and the plotted data["amplitude"].

Examples

>>> phi.plasma.plot.mode_map(t=-1, m_range=(0, 16))

mode_profilesmethod#

def mode_profiles(omega: float | None = None, *, x: str | None = None, dims=None, x_of=None, xlabel: str | None = None, top: int = 4, phase: bool = True, scale=None, backend: Backend | None = None, **selection)

Plot the radial profile of each (m, n) harmonic of this field.

Parameters

NameTypeDefaultDescription
omegafloatNoneA frequency: the eigenfunction at that frequency (amplitude and phase), mode_spectrum(mode_structure(field, omega)). Default: the harmonics’ amplitudes at one time, which is then selected by keyword (e.g. t=-1).
xstrNoneThe radial dimension. Default: the radial logical one (eta1, or GVEC’s rho).
dimssequence of strNoneThe periodic dimensions to decompose. Default: the two logical angles, ("eta2", "eta3") or GVEC’s (see plasma_plots.spectral.mode_spectrum()).
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.
scaleint or sequence of intNoneMultiplies the mode numbers, e.g. (1, 6) for full-torus n of a sixth of a torus. Default: 1, or nfp along GVEC’s toroidal angle (see plasma_plots.spectral.mode_spectrum()).
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Dimensions to select first (without omega, the time): an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes, the drawn lines and the plotted data["profiles"].

Raises

ValueError
Without omega, if t is not selected.

Examples

>>> phi.plasma.plot.mode_profiles(
... omega, x_of=lambda eta1: 0.1 + 0.9 * eta1, top=2
... )
>>> phi.plasma.plot.mode_profiles(t=-1, scale=(1, 6))

moviemethod#

def movie(path, *, kind: Literal['isosurface', 'slices', 'glyphs', 'streamlines'] = 'slices', step: int = 1, framerate: int = 10, clim=None, **options)

Render one PyVista 3-D view per time step into a GIF or video.

Every dimension but t and the spatial (and component) dimensions must already be selected.

Parameters

NameTypeDefaultDescription
pathstr or pathlib.PathrequiredThe output file: a GIF for .gif, a video (e.g. .mp4) for any other suffix.
kind('isosurface', 'slices', 'glyphs', 'streamlines')"isosurface"The view of each frame. Default: "slices".
stepint1Use every step-th position of sweep. Default: 1.
framerateint10Frames per second. Default: 10.
clim(float, float)NoneColor limits of the scalar views ("isosurface", "slices"). Default: from the whole sweep, with the symmetric and robust options.
**options{}Options of the chosen view, e.g. cuts= for kind="slices" (see slices_3d(), isosurface(), glyphs(), streamlines()).

Returns

str
The path of the written file.

Examples

>>> phi.plasma.plot.movie(
... "mode.gif",
... kind="slices",
... cuts={"eta3": [0, 0.25, 0.5, 0.75]},
... cmap="RdBu_r",
... )

overlay_orbitsmethod#

def overlay_orbits(orbits: xr.Dataset, *, x: str, y: str, max_markers: int = 200, ax=None, cmap=None, backend: Backend | None = None, **selection)

Plot this field’s slice with marker orbit paths from orbits overlaid.

A Poincare-style diagnostic for checking particle confinement or orbit topology against a background field.

Parameters

NameTypeDefaultDescription
orbitsxarray.DatasetrequiredAn orbits product with position variables named after view.x and view.y (e.g. its logical coordinates, to overlay directly on a logical-coordinates slice).
xstrrequiredThe horizontal dimension of the slice. orbits must have a position variable of the same name (e.g. logical eta1, to overlay directly on a logical-coordinates slice of this field).
ystrrequiredThe vertical dimension of the slice; orbits needs a variable of this name too.
max_markersint200Draw only the first max_markers markers. Default: 200.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
cmapstr or matplotlib.colors.ColormapNoneThe colormap of the field. Default: "viridis".
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every other dimension of this field, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes, the slice’s mesh and one line per orbit.

Examples

>>> phi.plasma.plot.overlay_orbits(orbits, x="eta1", y="eta2", t=-1, eta3=0)

panelsmethod#

def panels(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', vmin=None, vmax=None, shared_clim: bool = True, cmap: str | None = None, equal_aspect: bool | None = None, title: str | None = None, symmetric: bool = False, robust: bool = False, levels=None, fill: bool = True, overlays: dict | None = None, xlabel: str | None = None, ylabel: str | None = None, colorbar_label: str | None = None, nrows: int = 3, ncols: int = 4, backend: Backend | None = None, **selection)

Render evenly spaced snapshots along the sweep.

The same as plot.view(...).panels(nrows=nrows, ncols=ncols); see view() for the shared options.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
vminfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
vmaxfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
shared_climboolTrueFix the color limits over all selected data, including frames omitted by a panel layout or export step; False rescales each frame. Default: True.
cmapstrNoneThe colormap. Default: the Struphy style’s.
equal_aspectboolNoneEqual axis scales. Default: True for physical coordinates, else False.
titlestrNoneThe title. Default: the array’s label.
symmetricboolFalseCenter the color limits on zero, for perturbations with a diverging cmap. Default: False.
robustboolFalseTake the color limits from the 1st/99th percentiles, so a few outliers do not wash out the rest. Default: False.
levelsint or sequence of floatNoneContour lines of the field on top, e.g. an interface or flux surfaces: a number of evenly spaced levels, or explicit values. Default: none.
fillboolTrueDraw the colored field; with False only the levels lines are drawn, colored by cmap. Default: True.
overlaysdictNoneFurther elements on top: contours_of (a second field whose contour lines are drawn, e.g. the flux function over the current; with contour_levels, contour_color), boundary=True (the grid’s outline), grid_lines=n (every n-th grid line), lines (label to (x, y) or a function y(x), e.g. characteristics on a space-time map) and points (label to (x, y)), in line_color and point_color (white by default, for dark colormaps).
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s name and units.
ylabelstrNoneThe vertical axis label. Default: the coordinate’s name and units.
colorbar_labelstrNoneThe color bar label. Default: the array’s label and units.
nrowsint3The number of panel rows. Default: 3.
ncolsint4The number of panel columns. Default: 4.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

PlotResult
The figure, the array of axes and the drawn meshes.

Examples

>>> phi.plasma.plot.panels(x="eta1", y="eta2", nrows=2, ncols=3, eta3=0)

pencil_fitmethod#

def pencil_fit(n_modes: int = 1, pencil: int | None = None, detrend: bool = False, backend: Backend | None = None, **selection)

Plot a matrix-pencil fit of this (t,) series.

The samples against the fit, and the modes in the complex-frequency plane.

Parameters

NameTypeDefaultDescription
n_modesint1The number of modes to fit and return: real oscillations for a real signal, complex exponentials for a complex one. The fit needs well over 2 * n_modes samples. Default: 1.
pencilintNoneThe pencil parameter (Hankel matrix width minus one), which trades noise robustness against resolution. Default: N // 2.
detrendboolFalseSubtract the mean first. Default: False.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but t, e.g. a probe point: an integer is a position, a float the nearest coordinate value.

Returns

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

Examples

>>> probe.plasma.plot.pencil_fit(n_modes=1)

poincaremethod#

def poincare(seeds=8, turns: float | None = None, section: float | None = None, coords: str = 'physical', color_by: str | None = 'line', islands: bool = False, boundary: xr.DataArray | None = None, ax=None, backend: Backend | None = None, **selection)

Trace field lines of this vector field and plot their Poincaré section.

A convenience for ArrayAnalysis.field_lines() followed by DatasetPlots.poincare(); keep the traced lines (result.data["lines"]) to plot them again, cut another plane or sample a field along them.

Parameters

NameTypeDefaultDescription
seeds(int, dict, array_like or xarray.Dataset)8Where the lines start; see plasma_plots.fieldlines.trace_field_lines(). Default: 8 along the radius.
turnsfloatNoneHow many toroidal transits to trace. Default: 20.
sectionfloatNoneThe toroidal logical coordinate of the plane. Default: the first grid value.
coords('physical', 'logical')"physical"Draw R against z (physical), or the poloidal angle against the radial logical coordinate (logical). Default: "physical".
color_by('line', 'iota', 'classification', 'connection_length', None)"line"One color per line (cycling), a color bar over each line’s rotational transform or connection length, or the classes of classify_field_lines() (surface, island, chaotic) with a legend; None for one color. Default: "line".
islandsboolFalseLabel the island chains with their n/m and widths. Default: False.
boundaryxarray.DataArrayNoneA field with physical coordinates whose outermost surface is drawn at the section (physical coordinates only).
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The other dimensions, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the scatters; data["lines"] holds the traced lines, data["section"] the punctures.

Examples

>>> B.plasma.plot.poincare(seeds=12, turns=100, t=-1)
>>> B.plasma.plot.poincare(color_by="classification", islands=True, t=-1)

power_spectrummethod#

def power_spectrum(dims=None, detrend: bool = True, window: str | None = None, peaks: int | None = None, band=None, frequencies: dict | None = None, logy: bool = True, omega_max: float | None = None, ax=None, title: str | None = None, backend: Backend | None = None, **selection)

Plot the power per frequency bin, averaged over dims.

dims defaults to all but component; optional peak labels, a shaded filter band and reference frequencies.

Parameters

NameTypeDefaultDescription
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.
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.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Dimensions other than t to select first (e.g. a probe point eta1=0.4): an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the drawn artists; data holds the averaged "power" and the found "peaks".

Examples

>>> band = phi.plasma.analysis.filter_time(dims=("eta1", "eta2", "eta3"))
>>> phi.plasma.plot.power_spectrum(
... peaks=2, band=band, frequencies={"TAE gap": omega_tae}
... )

profilesmethod#

def profiles(x: str | None = None, over: str = 't', at=None, x_of=None, xlabel: str | None = None, ax=None, title: str | None = None, reference=None, backend: Backend | None = None, **selection)

Plot profiles along x at several values of over in one axes.

By default four times. x_of maps x to the plotted axis (e.g. the minor radius); reference overlays the exact profiles (lambda x, t: ...).

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis. Default: the radial logical one (eta1, or GVEC’s rho).
overstr't'The dimension to draw one profile per value of. Default: "t".
atint, float or sequence of theseNoneThe values of over: integers are positions, floats nearest values. Default: four evenly spaced positions.
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.
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s label, or "r" with x_of.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe axes title. Default: the array’s label.
referencecallable, array, (x, y) pair or dictNoneExact or expected profiles, drawn in each profile’s color in dashed styles: a function of the plotted x (or of x and the value of over), a 1-D xarray.DataArray (drawn over its own coordinate), an (x, y) pair, or a dict of labels to these.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every other dimension, e.g. eta2=0.125, eta3=0: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the drawn lines.

Examples

>>> T.plasma.plot.profiles(
... x="eta1", at=[0, 10, 20, 40], reference={"exact": exact}
... )

radial_powermethod#

def radial_power(x: str | None = None, x_of=None, xlabel: str | None = None, continuum=None, detrend: bool = True, window: str | None = None, log: bool = True, dynamic_range: float = 3.0, omega_max: float | None = None, ax=None, backend: Backend | None = None, **selection)

Plot the time-power over (omega, x), averaged over the other dimensions.

The other dimensions are e.g. the angles; optional continuous spectra are drawn on top.

Parameters

NameTypeDefaultDescription
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().
detrendboolTrueSubtract the temporal mean first. Default: True.
window(None, 'hann')NoneThe taper of the time FFT. Default: None (boxcar).
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.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Dimensions to select first: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes, the drawn artists and the plotted data["power"].

Examples

>>> phi.plasma.plot.radial_power(
... x_of=lambda eta1: 0.1 + 0.9 * eta1, omega_max=0.5
... )

slicemethod#

def slice(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', vmin=None, vmax=None, shared_clim: bool = True, cmap: str | None = None, equal_aspect: bool | None = None, title: str | None = None, symmetric: bool = False, robust: bool = False, levels=None, fill: bool = True, overlays: dict | None = None, xlabel: str | None = None, ylabel: str | None = None, colorbar_label: str | None = None, ax=None, backend: Backend | None = None, **selection)

Render one 2-D slice.

The same as plot.view(...).slice(ax=ax); see view() for the shared options.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
vminfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
vmaxfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
shared_climboolTrueFix the color limits over all selected data, including frames omitted by a panel layout or export step; False rescales each frame. Default: True.
cmapstrNoneThe colormap. Default: the Struphy style’s.
equal_aspectboolNoneEqual axis scales. Default: True for physical coordinates, else False.
titlestrNoneThe title. Default: the array’s label.
symmetricboolFalseCenter the color limits on zero, for perturbations with a diverging cmap. Default: False.
robustboolFalseTake the color limits from the 1st/99th percentiles, so a few outliers do not wash out the rest. Default: False.
levelsint or sequence of floatNoneContour lines of the field on top, e.g. an interface or flux surfaces: a number of evenly spaced levels, or explicit values. Default: none.
fillboolTrueDraw the colored field; with False only the levels lines are drawn, colored by cmap. Default: True.
overlaysdictNoneFurther elements on top: contours_of (a second field whose contour lines are drawn, e.g. the flux function over the current; with contour_levels, contour_color), boundary=True (the grid’s outline), grid_lines=n (every n-th grid line), lines (label to (x, y) or a function y(x), e.g. characteristics on a space-time map) and points (label to (x, y)), in line_color and point_color (white by default, for dark colormaps).
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s name and units.
ylabelstrNoneThe vertical axis label. Default: the coordinate’s name and units.
colorbar_labelstrNoneThe color bar label. Default: the array’s label and units.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

PlotResult
The figure, the axes and the drawn mesh.

Examples

>>> phi.plasma.plot.slice(x="eta1", y="eta2", t=-1)
>>> n.plasma.plot.slice(
... coords="physical", plane="XY", t=-1, eta3=0, levels=[0.2]
... )

slices_3dmethod#

def slices_3d(cuts: dict | None = None, cmap='viridis', clim=None, show_domain: bool = True, title: str | None = None, symmetric: bool = False, robust: bool = False, plotter=None, **selection)

Draw PyVista surfaces of constant logical coordinate in physical space.

E.g. cuts={"eta3": [0, 0.25]} for poloidal cross-sections, cuts={"eta1": 0.8} for one flux surface. A 2-D field is shown as its whole plane by default.

Parameters

NameTypeDefaultDescription
cutsdictNone{dim: position or list of positions} along eta1, eta2, eta3: a float is the nearest logical coordinate, an integer a grid index (-1 the last). Default: the middle of every dimension, or the whole plane of a 2-D field.
cmapstr or matplotlib colormap'viridis'The colormap. Default: "viridis".
clim(float, float)NoneColor limits, shared by every cut; default from the whole field’s values, see symmetric and robust.
show_domainboolTrueDraw the domain’s outer surface translucently for context. Not drawn when the whole plane of a 2-D field is shown. Default: True.
titlestrNoneText in the scene’s corner. Default: the field’s label; "" for none.
symmetricboolFalseColor limits symmetric about zero. Default: False.
robustboolFalseColor limits from percentiles instead of the extremes, so outliers don’t wash out the colors. Default: False.
plotterpyvista.PlotterNoneDraw into this scene instead of a new one, to combine several views. The camera is only aimed at the field when this function creates the plotter.
**selection{}Every dimension but eta1, eta2, eta3, e.g. t=0: an integer is a position, a float the nearest coordinate value.

Returns

pyvista.Plotter
The plotter with the cuts, not yet shown.

Examples

>>> phi.plasma.plot.slices_3d(
... cuts={"eta3": [0, 0.25, 0.5, 0.75]}, cmap="RdBu_r", t=0
... ).show()

spectrogrammethod#

def spectrogram(length, step=None, detrend: bool = True, window: str | None = 'hann', log: bool = True, dynamic_range: float = 4.0, omega_max: float | None = None, frequencies: dict | None = None, ax=None, backend: Backend | None = None, **selection)

Plot short-time power spectra over (t, omega).

Any dimensions that remain after selection are averaged.

Parameters

NameTypeDefaultDescription
lengthint or floatrequiredThe window length: a number of samples (integer) or a time span (float).
stepint or floatNoneThe shift between windows, in the same forms. Default: a quarter of length.
detrendboolTrueSubtract each window’s mean first. Default: True.
window('hann', None)"hann"The taper of each window. Default: "hann".
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.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Dimensions other than t to select first: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the drawn artists; data["spectrogram"] is the power.

Examples

>>> signal.plasma.plot.spectrogram(length=200.0, step=10.0, omega_max=0.45)

streamlinesmethod#

def streamlines(components: Literal['cartesian', 'contravariant'] = 'cartesian', n_points: int = 100, source_radius: float | None = None, source_center=None, max_length: float | None = None, tube_radius: float | None = None, cmap='viridis', show_domain: bool = True, title: str | None = None, plotter=None, **selection)

Draw PyVista field lines of this vector field, e.g. magnetic field lines.

Parameters

NameTypeDefaultDescription
components('cartesian', 'contravariant')"cartesian"How to read the components: Cartesian x/y/z, or contravariant logical components, pushed forward by [push_forward()][push_forward]. Default: "cartesian".
n_pointsint100The number of seed points (at most the number of grid points when seeding on the grid). Default: 100.
source_radiusfloatNoneSeed in a sphere of this radius instead of at grid points. Default (when source_center is given): a quarter of the domain size.
source_center(float, float, float)NoneSeed in a sphere around this physical point instead of at grid points. Default (when source_radius is given): the bounding-box center.
max_lengthfloatNoneMaximum length of each line. Default: four times the domain size.
tube_radiusfloatNoneDraw the lines as tubes of this radius. Default: plain lines.
cmapstr or matplotlib colormap'viridis'The colormap of the magnitude. Default: "viridis".
show_domainboolTrueDraw the domain’s outer surface translucently for context. Default: True.
titlestrNoneText in the scene’s corner. Default: "<label> field lines"; "" for none.
plotterpyvista.PlotterNoneDraw into this scene instead of a new one, to combine several views. The camera is only aimed at the field when this function creates the plotter.
**selection{}Every dimension but component, eta1, eta2, eta3, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

pyvista.Plotter
The plotter with the field lines, not yet shown.

Examples

>>> B.plasma.plot.streamlines(
... n_points=60, source_center=(3.5, 0, 0), t=-1
... ).show()

surface_mapmethod#

def surface_map(x: str | None = None, y: str | None = None, iota=None, lines: xr.Dataset | None = None, count: int = 6, start: float = 0.0, turns: float | None = 2.0, line_color: str = 'w', ax=None, backend: Backend | None = None, **options)

Plot this quantity on one flux surface, unfolded over the angles, with field lines.

Select the surface and the time by keyword, e.g. rho=0.5 or eta1=0.5, t=-1. Field lines are straight lines of slope ι in straight-field-line angles (Boozer, PEST), or traced lines (ArrayAnalysis.field_lines()) on any grid.

Parameters

NameTypeDefaultDescription
xstrNoneThe toroidal angle. Default: the toroidal logical dimension.
ystrNoneThe poloidal angle. Default: the poloidal logical dimension.
iotafloat or xarray.DataArrayNoneThe rotational transform of the surface, or its profile over the radial coordinate, at whose value in data’s coordinates it is interpolated. Draws count straight field lines. Default: none.
linesxarray.DatasetNoneTraced lines (trace_field_lines()), drawn over the angles as they are, every line in the Dataset. Default: none.
countint6The number of straight lines, equally spaced in the poloidal angle. Default: 6.
startfloat0.0The poloidal angle of the first straight line at the left edge. Default: 0.
turnsfloat2.0How many toroidal transits of each traced line to draw (a long line covers an irrational surface completely); None for all. Default: 2.
line_colorstr'w'The color of the field lines. Default: white.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**options{}The remaining dimensions to select (an integer is a position, a float the nearest value), and the options of plasma_plots.plotting.plot_slice() (cmap, levels, overlays, …).

Returns

PlotResult
The figure, the axes, the mesh and the lines; data["iota"] holds the ι drawn.

Examples

>>> boozer.mod_B.plasma.plot.surface_map(rho=0.5, iota=boozer.iota, count=8)
>>> phi.plasma.plot.surface_map(eta1=0.5, t=-1, lines=lines)

timeseriesmethod#

def timeseries(*others, logy: bool = True, fit=None, fit_amplitude: bool = False, title: str | None = None, ax=None, reference=None, backend: Backend | None = None)

Plot this time series, and any others given, in one axes.

Parameters

NameTypeDefaultDescription
*others()Further arrays with the single dimension t; they may come from other runs and need not share this array’s time grid.
logyboolTrueUse a logarithmic value axis. Default: True.
fit(float or None, float or None) or boolNoneTime window (t0, t1) of an exponential fit per series (None for an open end), or True for the whole series. Rates are in result.fit_results. Default: no fit.
fit_amplitudeboolFalseThe series is quadratic in an amplitude (e.g. an energy); fit the amplitude’s rate. Default: False.
titlestrNoneThe axes title. Default: the first series’ label.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
referencecallable, array, (t, values) pair or dictNoneExact or expected curves, drawn dashed: a function of t, an array, a (t, values) pair, or a mapping of labels to these.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes, the drawn lines, and in fit_results one FitResult (or None) per series.

Examples

>>> energy.plasma.plot.timeseries(
... logy=True, fit=(0.0, 2.0), fit_amplitude=True
... )
>>> energy.plasma.plot.timeseries(other_run_energy)

trajectoriesmethod#

def trajectories(max_markers: int = 200, show_paths: bool | None = None, ax=None, backend: Backend | None = None)

Plot the three-dimensional paths of saved markers, for an orbit product.

Parameters

NameTypeDefaultDescription
max_markersint200Draw only the first max_markers markers. Default: 200.
show_pathsboolNoneDraw each marker’s path, not only its last position. Default: True for up to 200 markers.
axmpl_toolkits.mplot3d.Axes3DNoneA 3-D axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the 3-D axes and the drawn artists.

vectormethod#

def vector(x: str, y: str, components: tuple[int, int] = (0, 1), stride: int = 1, coordinates: Coordinates = 'logical', ax=None, backend: Backend | None = None, **selection)

Plot two vector components after selecting time and remaining dimensions.

Parameters

NameTypeDefaultDescription
xstrrequiredThe dimension along the horizontal axis.
ystrrequiredThe dimension along the vertical axis.
components(int, int)(0, 1)The positions along component_dim of the two components drawn. Default: (0, 1).
strideint1Draw every stride-th arrow along x and y. Default: 1.
coordinates('logical', 'physical')"logical"Place the arrows at the logical coordinates, or at the attached physical X, Y, Z (then x and y must be two of eta1, eta2, eta3, and the axes have equal scales). Default: "logical".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but x, y and the component dimension, e.g. t=-1, eta3=0: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the quiver.

Examples

>>> E.plasma.plot.vector(x="eta1", y="eta2", t=-1, eta3=0)

viewmethod#

def view(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', vmin=None, vmax=None, shared_clim: bool = True, cmap: str | None = None, equal_aspect: bool | None = None, title: str | None = None, symmetric: bool = False, robust: bool = False, levels=None, fill: bool = True, overlays: dict | None = None, xlabel: str | None = None, ylabel: str | None = None, colorbar_label: str | None = None, **selection) -> 'SliceView'

Configure a reusable slice view without rendering a figure.

Use xarray’s .sel()/.isel() for general selection, or pass remaining dimensions here. The options apply to every presentation of the view: slice(), panels(), viewer(), animation() and frames() take the same ones.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
vminfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
vmaxfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
shared_climboolTrueFix the color limits over all selected data, including frames omitted by a panel layout or export step; False rescales each frame. Default: True.
cmapstrNoneThe colormap. Default: the Struphy style’s.
equal_aspectboolNoneEqual axis scales. Default: True for physical coordinates, else False.
titlestrNoneThe title. Default: the array’s label.
symmetricboolFalseCenter the color limits on zero, for perturbations with a diverging cmap. Default: False.
robustboolFalseTake the color limits from the 1st/99th percentiles, so a few outliers do not wash out the rest. Default: False.
levelsint or sequence of floatNoneContour lines of the field on top, e.g. an interface or flux surfaces: a number of evenly spaced levels, or explicit values. Default: none.
fillboolTrueDraw the colored field; with False only the levels lines are drawn, colored by cmap. Default: True.
overlaysdictNoneFurther elements on top: contours_of (a second field whose contour lines are drawn, e.g. the flux function over the current; with contour_levels, contour_color), boundary=True (the grid’s outline), grid_lines=n (every n-th grid line), lines (label to (x, y) or a function y(x), e.g. characteristics on a space-time map) and points (label to (x, y)), in line_color and point_color (white by default, for dark colormaps).
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s name and units.
ylabelstrNoneThe vertical axis label. Default: the coordinate’s name and units.
colorbar_labelstrNoneThe color bar label. Default: the array’s label and units.
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

SliceView
The configured view; it creates no figure and does not copy the array.

Examples

>>> view = f.plasma.plot.view(x="eta1", y="v1", cmap="RdBu_r")
>>> view.slice(t=-1)
>>> view.panels(nrows=2, ncols=3)
>>> view.save_frames("frames")

viewermethod#

def viewer(x: str | None = None, y: str | None = None, sweep: str = 't', coords: Coordinates = 'logical', plane: Plane = 'XY', vmin=None, vmax=None, shared_clim: bool = True, cmap: str | None = None, equal_aspect: bool | None = None, title: str | None = None, symmetric: bool = False, robust: bool = False, levels=None, fill: bool = True, overlays: dict | None = None, xlabel: str | None = None, ylabel: str | None = None, colorbar_label: str | None = None, backend: Backend | None = None, **selection)

Create an interactive slider view; keep a reference to the returned viewer.

The same as plot.view(...).viewer(); see view() for the shared options.

Parameters

NameTypeDefaultDescription
xstrNoneThe dimension along the horizontal axis (logical coordinates). Default: the first of the two remaining dimensions.
ystrNoneThe dimension along the vertical axis. Default: the second remaining dimension.
sweepstr't'The dimension stepped through by panels, the viewer’s slider, animations and exported frames. Default: "t".
coords('logical', 'physical')"logical"Draw over the logical coordinates, or over the mapped physical coordinates (X, Y, Z). Default: "logical".
plane('XY', 'XZ', 'YZ', 'RZ', 'X1X2')"XY"The physical plane, with coords="physical": "RZ" uses R = √(X² + Y²), "X1X2" GVEC’s reference coordinates. Default: "XY".
vminfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
vmaxfloatNoneExplicit color limits; each overrides its limit with or without shared_clim.
shared_climboolTrueFix the color limits over all selected data, including frames omitted by a panel layout or export step; False rescales each frame. Default: True.
cmapstrNoneThe colormap. Default: the Struphy style’s.
equal_aspectboolNoneEqual axis scales. Default: True for physical coordinates, else False.
titlestrNoneThe title. Default: the array’s label.
symmetricboolFalseCenter the color limits on zero, for perturbations with a diverging cmap. Default: False.
robustboolFalseTake the color limits from the 1st/99th percentiles, so a few outliers do not wash out the rest. Default: False.
levelsint or sequence of floatNoneContour lines of the field on top, e.g. an interface or flux surfaces: a number of evenly spaced levels, or explicit values. Default: none.
fillboolTrueDraw the colored field; with False only the levels lines are drawn, colored by cmap. Default: True.
overlaysdictNoneFurther elements on top: contours_of (a second field whose contour lines are drawn, e.g. the flux function over the current; with contour_levels, contour_color), boundary=True (the grid’s outline), grid_lines=n (every n-th grid line), lines (label to (x, y) or a function y(x), e.g. characteristics on a space-time map) and points (label to (x, y)), in line_color and point_color (white by default, for dark colormaps).
xlabelstrNoneThe horizontal axis label. Default: the coordinate’s name and units.
ylabelstrNoneThe vertical axis label. Default: the coordinate’s name and units.
colorbar_labelstrNoneThe color bar label. Default: the array’s label and units.
backend('matplotlib', 'plotly')"matplotlib"Draw with Matplotlib, or as an interactive Plotly figure with a slider (in result.fig; needs plotly, see plasma_plots.plotly_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but x, y and sweep: an integer is a position (-1 the last), a float the nearest coordinate value. Checked now; a name that is not a dimension raises TypeError.

Returns

plasma_plots.plotting.InteractiveSliceViewer or PlotResult
The viewer, with sliders for the unselected dimensions; with backend="plotly" a result whose Plotly figure has one slider (one unselected dimension at most).

Examples

>>> viewer = phi.plasma.plot.viewer(x="eta1", y="eta2")

volumemethod#

def volume(name: str | None = None, cmap='viridis', opacity='linear', **selection)

Create a PyVista volume plotter for a selected scalar field.

Parameters

NameTypeDefaultDescription
namestrNoneThe name of the scalars in the PyVista grid. Default: the array’s label, else "value".
cmapstr'viridis'The colormap. Default: "viridis".
opacitystr or sequence of float'linear'PyVista’s opacity transfer function. Default: "linear".
**selection{}Every dimension but eta1, eta2, eta3, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

pyvista.Plotter
The plotter, not yet shown; call plotter.show().

Examples

>>> density.plasma.plot.volume(cmap="viridis", opacity="linear", t=-1).show()

volume_slicesmethod#

def volume_slices(indices: dict[str, int] | None = None, cmap=None, backend: Backend | None = None, **selection)

Render three orthogonal slices of a selected scalar volume.

Parameters

NameTypeDefaultDescription
indicesdict of str to intNoneThe index at which each dimension is held fixed, e.g. {"eta3": 0}. Default: the middle index of every dimension.
cmapstr or matplotlib.colors.ColormapNoneThe colormap. Default: Matplotlib’s default.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Every dimension but the three of the volume, e.g. t=-1: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the three axes and the drawn meshes.

Examples

>>> density.plasma.plot.volume_slices(t=-1)

DatasetAnalysisclass#

class DatasetAnalysis(dataset: xr.Dataset)

Quantitative diagnostics of one dataset, as dataset.plasma.analysis.<quantity>(...).

Examples

>>> orbits.plasma.analysis.classify_orbits()

bounce_periodmethod#

def bounce_period(v_par: str = 'v_par') -> xr.DataArray

Return the bounce period of each trapped marker.

Parameters

NameTypeDefaultDescription
v_parstr'v_par'The name of the parallel-velocity variable. Default: "v_par".

Returns

xarray.DataArray
The bounce period over marker.

Examples

>>> orbits.plasma.analysis.bounce_period()

classify_field_linesmethod#

def classify_field_lines(max_denominator: int = 12, tolerance: float | None = None, threshold: float = 0.1, min_spread: float | None = None) -> xr.DataArray

Classify each traced field line: on a flux surface (0), in an island (1) or chaotic (2).

Parameters

NameTypeDefaultDescription
max_denominatorint12The largest m of the rationals considered. Default: 12.
tolerancefloatNoneHow close ι must be to n/m. Default: two over the number of toroidal transits of the line (the resolution of ι from the trace), at least 1e-3.
thresholdfloat0.1The median radial jump between punctures that are neighbours in the poloidal angle, relative to the line’s radial spread, above which a non-librating line is chaotic (a smooth curve through 100 punctures gives a few hundredths). Default: 0.1.
min_spreadfloatNoneThe radial spread of the punctures (in the radial logical coordinate) below which a line is on a surface. Default: half the radial grid spacing of the traced field.

Returns

xarray.DataArray
The class of each line over line.

Examples

>>> lines.plasma.analysis.classify_field_lines()

classify_orbitsmethod#

def classify_orbits(v_par: str = 'v_par') -> xr.DataArray

Classify each marker of this guiding-center orbits product: passing (0), trapped (1) or lost (-1).

See plasma_plots.analysis.classify_orbits() for the criteria.

Parameters

NameTypeDefaultDescription
v_parstr'v_par'The name of the parallel-velocity variable. Default: "v_par".

Returns

xarray.DataArray
The class of each marker, over marker.

Examples

>>> orbits.plasma.analysis.classify_orbits()

footprintmethod#

def footprint() -> xr.Dataset

Return where these traced field lines left the grid, with their connection lengths.

Returns

xarray.Dataset
The exit points over line.

Examples

>>> edge.plasma.analysis.footprint()

islandsmethod#

def islands(max_denominator: int = 12, tolerance: float | None = None, threshold: float = 0.1, min_spread: float | None = None) -> xr.Dataset

Return the island chains these traced field lines show, with their widths.

Parameters

NameTypeDefaultDescription
max_denominatorint12The largest m of the rationals considered. Default: 12.
tolerancefloatNoneHow close ι must be to n/m; see classify_field_lines().
thresholdfloat0.1The chaos criterion of classify_field_lines(). Default: 0.1.
min_spreadfloatNoneThe surface criterion of classify_field_lines(). Default: half the radial grid spacing.

Returns

xarray.Dataset
Over chain: n, m, width, center, …

Examples

>>> lines.plasma.analysis.islands().to_dataframe()

loss_mapmethod#

def loss_map(x: str = 'v_par', y: str | None = None, t=0, absB=None) -> xr.Dataset

Return each marker’s initial phase-space position, whether it is lost, and when.

Parameters

NameTypeDefaultDescription
xstr'v_par'The first quantity. Default: "v_par".
ystrNoneThe second quantity. Default: "mu", or "v_perp" without mu.
tint or float0The time of the plotted values: an integer position (default 0, the initial one) or a float nearest value.
absBcallableNone|B|(x, y, z), for "energy" and "pitch" (see orbit_invariants()).

Returns

xarray.Dataset
x, y, lost and loss_time over marker.

Examples

>>> orbits.plasma.analysis.loss_map(x="energy", y="pitch", absB=absB)

lost_fractionmethod#

def lost_fraction(weight: str | None = None) -> xr.DataArray

Return the fraction of markers lost from the domain, over time.

Parameters

NameTypeDefaultDescription
weightstrNoneWeigh each marker by its initial value of this variable, e.g. "weight". Default: count the markers.

Returns

xarray.DataArray
The fraction over t.

Examples

>>> orbits.plasma.analysis.lost_fraction(weight="weight")

marker_densitymethod#

def marker_density(dims=('eta1'), bins=32, weight: str | None = None, ranges=None) -> xr.DataArray

Return the markers binned over position variables, per unit volume.

Parameters

NameTypeDefaultDescription
dimsstr or sequence of str('eta1')The position variables to bin over, e.g. ("eta1",) or ("x", "y"). Default: ("eta1",).
binsint or sequence of int32The number of bins, for all or for each. Default: 32.
weightstrNoneWeigh each marker by this variable, e.g. "weight". Default: count the markers.
rangesdictNone{variable: (low, high)} bin ranges. Default: (0, 1) for the logical eta coordinates, the markers’ extent otherwise.

Returns

xarray.DataArray
The density over t and the binned variables.

Examples

>>> orbits.plasma.analysis.marker_density(dims="eta1", weight="weight")

orbit_invariantsmethod#

def orbit_invariants(absB=None) -> xr.Dataset

Return the speed, guiding-centre energy and pitch of the saved orbits.

Parameters

NameTypeDefaultDescription
absBcallableNone|B|(x, y, z) as a function of the physical positions (numpy arrays), e.g. lambda x, y, z: out.equil.absB0(*out.domain.inverse_map(x, y, z)). Needed for the energy and the pitch.

Returns

xarray.Dataset
The invariants per marker and time.

Examples

>>> orbits.plasma.analysis.orbit_invariants(absB=absB_xyz)

poincare_sectionmethod#

def poincare_section(angle: float | None = None) -> xr.Dataset

Return the punctures of a poloidal plane by these traced field lines.

Parameters

NameTypeDefaultDescription
anglefloatNoneThe toroidal logical coordinate of the plane. Default: the traced section.

Returns

xarray.Dataset
The punctures over (puncture, line).

Examples

>>> lines.plasma.analysis.poincare_section(angle=np.pi / 5)

rotational_transformmethod#

def rotational_transform() -> xr.DataArray

Return the rotational transform of each traced field line.

Returns

xarray.DataArray
iota over line.

Examples

>>> lines.plasma.analysis.rotational_transform()

seed_gridmethod#

def seed_grid(name: str = 'connection_length') -> xr.DataArray

Return a per-line quantity of these field lines over their grid of seeds.

Parameters

NameTypeDefaultDescription
namestr'connection_length'The per-line variable. Default: "connection_length".

Returns

xarray.DataArray
name over the two varying seed coordinates.

Examples

>>> edge.plasma.analysis.seed_grid("connection_length").plasma.plot.slice()

surface_averagemethod#

def surface_average(name: str, *, jacobian: str | None = 'Jac', domain=None, quadrature=None) -> xr.DataArray

Return the flux-surface average of one variable, with this Dataset’s Jacobian.

Parameters

NameTypeDefaultDescription
namestrrequiredThe variable, e.g. "mod_B".
jacobianstr or None'Jac'The variable holding √g, used if the Dataset has it. None (or a missing variable) takes domain, else the numerical Jacobian of X, Y, Z. Default: "Jac", GVEC’s.
domainstruphy domainNoneThe mapping, for the exact √g of a Struphy run.
quadraturedictNoneExplicit weights for the angles, as for [volume_integral()][volume_integral].

Returns

xarray.DataArray
⟨name⟩ over the radius and every non-spatial dimension.

Examples

>>> ev.plasma.analysis.surface_average("mod_B")

weight_statisticsmethod#

def weight_statistics(weight: str = 'weight') -> xr.Dataset

Return the statistics of the marker weights over time, with the noise estimate.

Parameters

NameTypeDefaultDescription
weightstr'weight'The weight variable. Default: "weight", Struphy’s.

Returns

xarray.Dataset
mean, std, total, noise, effective_markers, … over t.

Examples

>>> orbits.plasma.analysis.weight_statistics().noise.plasma.plot.timeseries()

DatasetDataclass#

class DatasetData(dataset: xr.Dataset)

The data behind each plot in DatasetPlots, without rendering it.

Examples

>>> markers.plasma.data.scatter(x="x", y="y", t=-1).to_dataframe()

footprintmethod#

def footprint() -> xr.Dataset

Return the exit points DatasetPlots.footprint() would plot.

Returns

xarray.Dataset
The exit points over line, with the connection lengths.

Examples

>>> edge.plasma.data.footprint()

loss_mapmethod#

def loss_map(x: str = 'v_par', y: str | None = None, t=0, absB=None) -> xr.Dataset

Return the per-marker values DatasetPlots.loss_map() would plot.

Parameters

NameTypeDefaultDescription
xstr'v_par'The first quantity. Default: "v_par".
ystrNoneThe second quantity. Default: "mu", or "v_perp" without mu.
tint or float0The time of the plotted values: an integer position (default 0, the initial one) or a float nearest value.
absBcallableNone|B|(x, y, z), for "energy" and "pitch" (see [orbit_invariants()][orbit_invariants]).

Returns

xarray.Dataset
x, y, lost and loss_time over marker.

Examples

>>> orbits.plasma.data.loss_map(x="energy", y="pitch", absB=absB)

orbit_classificationmethod#

def orbit_classification(x: str = 'v_par', y: str | None = None, v_par: str = 'v_par', t=0) -> xr.Dataset

Return the per-marker x, y and classification that orbit_classification plots.

The values DatasetPlots.orbit_classification() would plot.

Parameters

NameTypeDefaultDescription
xstr'v_par'The quantity along the horizontal axis. Default: "v_par".
ystrNoneThe quantity along the vertical axis. Default: the magnetic moment mu (Particles5D), or v_perp if there is no mu (Particles5Dvperp).
v_parstr'v_par'The parallel velocity the classification uses. Default: "v_par".
tint or float0The time of the plotted values: an integer position (default 0, the initial phase-space position, before any marker is lost; -1 the last), or a float nearest value.

Returns

xarray.Dataset
x, y and classification over marker.

Examples

>>> orbits.plasma.data.orbit_classification(x="p_phi")

poincaremethod#

def poincare(angle: float | None = None) -> xr.Dataset

Return the punctures DatasetPlots.poincare() would plot.

Parameters

NameTypeDefaultDescription
anglefloatNoneThe toroidal logical coordinate of the plane. Default: the traced section.

Returns

xarray.Dataset
The punctures over (puncture, line).

Examples

>>> lines.plasma.data.poincare().to_dataframe()

scattermethod#

def scatter(x: str, y: str, color: str | None = None, color_at=None, **selection) -> xr.Dataset

Return the per-marker positions and colors DatasetPlots.scatter() would plot.

.to_dataframe() hands them straight to e.g. Plotly Express.

Parameters

NameTypeDefaultDescription
xstrrequiredThe variables for the horizontal and vertical axes.
ystrrequiredThe variables for the horizontal and vertical axes.
colorstrNoneThe variable to color by. Default: none.
color_atint or floatNoneTake the colors at another time (an integer position such as 0, or a float value). Default: at the selected time.
**selection{}The other dimensions, e.g. t: an integer is a position (t=-1 the last), a float the nearest coordinate value.

Returns

xarray.Dataset
x, y and color over marker.

Examples

>>> markers.plasma.data.scatter(
... x="x", y="y", color="density", t=-1
... ).to_dataframe()
>>> # colored by the start
>>> markers.plasma.data.scatter(x="x", y="y", color="x", color_at=0, t=-1)

trajectoriesmethod#

def trajectories(max_markers: int = 200) -> xr.Dataset

Return the marker-position subset DatasetPlots.trajectories() would plot.

Parameters

NameTypeDefaultDescription
max_markersint200Draw only the first max_markers markers. Default: 200.

Returns

xarray.Dataset
The orbits of the first max_markers markers.

Raises

ValueError
If the orbits lack x, y or z, or a marker dimension.

Examples

>>> markers.plasma.data.trajectories(max_markers=50)

DatasetPlotsclass#

class DatasetPlots(dataset: xr.Dataset)

Plots of one dataset, as dataset.plasma.plot.<kind>(...).

Most of them are for an orbits product, with one (t, marker) variable per saved quantity; others plot the Dataset results of a spectral analysis.

Examples

>>> orbits.plasma.plot.trajectories()
>>> orbits.plasma.plot.orbit_classification()

animationmethod#

def animation(x: str, y: str, color: str | None = None, color_at=None, background: xr.DataArray | None = None, background_options: dict | None = None, step: int = 1, max_frames: int | None = None, interval: int = 100, s: int = 8, cmap=None, trail: int | None = None, paths: bool = False, backend: Backend | None = None)

Animate the markers moving over time, optionally over a field animated in sync.

E.g. over an SPH density. Keep a reference to the returned animation.

Parameters

NameTypeDefaultDescription
xstrrequiredThe data variable along the horizontal axis, e.g. the position "x"; "R" is √(x² + y²) when the data has no R of its own (with y="z" the poloidal plane).
ystrrequiredThe data variable along the vertical axis, e.g. the position "y".
colorstrNoneA variable to color by: per frame, or fixed at the time color_at; or "classification", the orbit class of each marker (passing, trapped, lost; needs v_par, see classify_orbits()), with a legend. Default: one color.
color_atint or floatNoneFix the colors at this time (an integer position, e.g. 0 for the initial position, to follow fluid parcels, or a float value). Default: the colors of each frame.
backgroundxarray.DataArrayNoneA field drawn behind the markers: with a t dimension (other dimensions selected) at the nearest time of each frame, with shared color limits; without one, fixed (drawn once). On its own x/y dimensions if it has them (a Cartesian field), in logical coordinates if x/y are eta1/eta2/eta3, else in the physical plane of x/y (the field then needs its X, Y, Z coordinates).
background_optionsdictNoneRendering options for the background, as for [plot_slice()][plot_slice] (cmap, symmetric, levels, …).
stepint1Use every step-th time. Default: 1.
max_framesintNoneKeep at most this many frames, evenly spaced over those step leaves (the first and last included), e.g. to keep a Plotly animation small. Default: all.
intervalint100The delay between frames, in milliseconds. Default: 100.
sint8The marker size, in points². Default: 8.
cmapstr or matplotlib.colors.ColormapNoneThe colormap for color. Default: "viridis".
trailintNoneDraw each marker’s last trail samples as a faint line behind it. Default: none.
pathsboolFalseDraw each marker’s whole path, fixed and faint, under the animation. Default: False.
backend('matplotlib', 'plotly')"matplotlib"Draw with Matplotlib, or as an interactive Plotly figure with a slider (in result.fig; needs plotly, see plasma_plots.plotly_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

matplotlib.animation.FuncAnimation or PlotResult
The animation; with backend="plotly" a result whose Plotly figure has a slider and Play/Pause buttons.

Examples

>>> markers.plasma.plot.animation(
... x="x", y="y", color="density", background=n, step=2
... )
>>> orbits.plasma.plot.animation(
... x="R",
... y="z",
... color="classification",
... trail=300,
... paths=True,
... background=psi,
... )

connection_lengthmethod#

def connection_length(log: bool = True, cmap=None, s: float = 14.0, ax=None, title: str | None = None, backend: Backend | None = None)

Plot the connection length of each field line over its seed.

Parameters

NameTypeDefaultDescription
logboolTrueShow the decimal logarithm of the connection length. Default: True.
cmapstr or matplotlib colormapNoneThe colormap. Default: "viridis".
sfloat14.0The marker size of a scatter, in points². Default: 14.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: "connection length".
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the mesh or scatter; data["connection_length"].

Examples

>>> edge.plasma.plot.connection_length()

cross_spectrummethod#

def cross_spectrum(omega_max: float | None = None, backend: Backend | None = None)

Plot the magnitude, coherence and phase of a cross_spectrum Dataset.

Parameters

NameTypeDefaultDescription
omega_maxfloatNoneThe highest frequency shown. Default: all.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn artists; data holds "peak_omega" and "peak_phase_deg".

Examples

>>> u.plasma.analysis.cross_spectrum(
... b, dims="eta3"
... ).plasma.plot.cross_spectrum(omega_max=1.5)

field_linesmethod#

def field_lines(plane: str = 'RZ', color_by: str | None = 'line', max_lines: int = 200, cmap=None, boundary: xr.DataArray | None = None, ax=None, title: str | None = None, backend: Backend | None = None)

Plot these traced field lines projected onto a plane, or in 3-D.

Parameters

NameTypeDefaultDescription
plane('RZ', 'XY', 'XZ', 'YZ', '3d')"RZ"The projection: the poloidal plane R-z (default), a Cartesian plane, or a 3-D axes.
color_by('line', 'iota', 'absB', 's', None)"line"One color per line (cycling), each line colored by its rotational transform, or each line colored along its path by |B| or the arc length s (with a color bar; 2-D planes only); None for one color. Default: "line".
max_linesint200Draw only the first max_lines lines. Default: 200.
cmapstr or matplotlib colormapNoneThe colormap. Default: "viridis".
boundaryxarray.DataArrayNoneA field with physical coordinates whose outermost surface is drawn in the RZ plane.
axmatplotlib.axes.AxesNoneThe axes to draw into (a 3-D axes for plane="3d"). Default: a new figure.
titlestrNoneThe title. Default: the lines’ label.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the lines.

Examples

>>> lines.plasma.plot.field_lines(plane="RZ", color_by="iota")
>>> lines.plasma.plot.field_lines(plane="3d", max_lines=20)

footprintmethod#

def footprint(log: bool = True, s: float = 14.0, cmap=None, ax=None, title: str | None = None, backend: Backend | None = None)

Plot where these open field lines leave the grid, colored by connection length.

Parameters

NameTypeDefaultDescription
logboolTrueColor by the decimal logarithm of the connection length. Default: True.
sfloat14.0The marker size, in points². Default: 14.
cmapstr or matplotlib colormapNoneThe colormap. Default: "viridis".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: how many lines left the grid.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the scatter; data["footprint"] holds the exit points.

Examples

>>> edge.plasma.plot.footprint()

loss_mapmethod#

def loss_map(x: str = 'v_par', y: str | None = None, t=0, absB=None, ax=None, s: int = 10, cmap=None, title: str | None = None, backend: Backend | None = None)

Plot which markers are lost, over their initial phase-space position, colored by when.

Parameters

NameTypeDefaultDescription
xstr'v_par'The quantity along the horizontal axis: a variable, or "energy", "pitch" or "speed" (see loss_map()). Default: "v_par".
ystrNoneThe vertical one. Default: "mu", or "v_perp" without mu.
tint or float0The time of the plotted positions: an integer position (default 0) or a float nearest value.
absBcallableNone|B|(x, y, z), for "energy" and "pitch".
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
sint10The marker size, in points². Default: 10.
cmapstr or matplotlib.colors.ColormapNoneThe colormap of the loss time. Default: "plasma".
titlestrNoneThe title. Default: how many markers are lost.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the scatters; data["losses"].

Examples

>>> orbits.plasma.plot.loss_map(x="energy", y="pitch", absB=absB)

lost_fractionmethod#

def lost_fraction(weight: str | None = None, percent: bool = True, ax=None, title: str | None = None, backend: Backend | None = None)

Plot the fraction of markers lost from the domain, against time.

Parameters

NameTypeDefaultDescription
weightstrNoneWeigh each marker by its initial value of this variable, i.e. count particles rather than markers. Default: count markers.
percentboolTrueShow percentages. Default: True.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: the final fraction.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the line; data["lost_fraction"].

Examples

>>> orbits.plasma.plot.lost_fraction(weight="weight")

marker_densitymethod#

def marker_density(x: str = 'eta1', weight: str | None = 'weight', against: xr.DataArray | None = None, bins: int = 32, normalize: bool = True, ax=None, title: str | None = None, backend: Backend | None = None, **selection)

Plot where the markers are against what they represent, along one coordinate.

Parameters

NameTypeDefaultDescription
xstr'eta1'The position variable to bin over, e.g. "eta1" or "x". Default: "eta1".
weightstr'weight'The weight variable, for the weighted density; None leaves it out. Default: "weight" (skipped when the Dataset has no such variable).
againstxarray.DataArrayNoneA reference profile over the same coordinate (every other dimension selected, or with t matching markers), drawn dashed. Default: none.
binsint32The number of bins. Default: 32.
normalizeboolTrueDivide each profile by the mean of its magnitude, so that the shapes compare (a δf perturbation sums to nearly nothing, so its plain mean would not do). Default: True.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: "marker density".
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The time: t=-1 (default, the last) or a float nearest value.

Returns

PlotResult
The figure, the axes and the lines; data holds the densities.

Examples

>>> orbits.plasma.plot.marker_density(
... x="eta1", against=n.isel(eta2=0, eta3=0), t=-1
... )

orbit_classificationmethod#

def orbit_classification(x: str = 'v_par', y: str | None = None, v_par: str = 'v_par', t=0, ax=None, s: int = 8, backend: Backend | None = None)

Plot markers in a phase-space plane, colored as passing, trapped or lost.

By default initial v_par against mu; for a guiding-center orbits product.

Parameters

NameTypeDefaultDescription
xstr'v_par'The quantity along the horizontal axis. Default: "v_par".
ystrNoneThe quantity along the vertical axis. Default: the magnetic moment mu (Particles5D), or v_perp if there is no mu (Particles5Dvperp).
v_parstr'v_par'The parallel velocity the classification uses. Default: "v_par".
tint or float0The time of the plotted values: an integer position (default 0, the initial phase-space position, before any marker is lost; -1 the last), or a float nearest value.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
sint8The marker size, in points². Default: 8.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn artists; data["counts"] holds the number of markers per class.

Examples

>>> orbits.plasma.plot.orbit_classification()
>>> orbits.plasma.plot.orbit_classification(x="p_phi")

orbit_gridmethod#

def orbit_grid(markers=8, ncols: int = 4, boundary: xr.DataArray | None = None, backend: Backend | None = None)

Plot one small poloidal panel per marker, colored by orbit class.

Parameters

NameTypeDefaultDescription
markersint or sequence of int8A number of markers (spread over the classes when v_par is saved) or a list of marker indices. Default: 8.
ncolsint4The number of panels per row. Default: 4.
boundaryxarray.DataArrayNoneA field with physical coordinates whose outer (last eta1) surface is drawn in every panel, at its first eta3.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn lines; data["markers"] holds the plotted markers.

Examples

>>> orbits.plasma.plot.orbit_grid(markers=8, ncols=4, boundary=field)
>>> orbits.plasma.plot.orbit_grid(markers=[3, 17, 42])

orbits_3dmethod#

def orbits_3d(color_by: str = 't', max_markers: int = 200, tube_radius: float | None = None, cmap=None, domain: xr.DataArray | None = None, title: str | None = None, plotter=None)

Draw PyVista 3-D orbit lines, colored by "t", "classification" or any variable.

domain is a field whose boundary is drawn for context.

Parameters

NameTypeDefaultDescription
color_bystr't'"t", "classification" (passing, trapped, lost, with a legend) or the name of any (t, marker) variable, e.g. "v_par". Default: "t".
max_markersint200At most this many markers are drawn. Default: 200.
tube_radiusfloatNoneDraw the orbits as tubes of this radius. Default: plain lines.
cmapstr or matplotlib colormapNoneThe colormap (not used for "classification"). Default: "viridis".
domainxarray.DataArrayNoneA field with physical coordinates whose outer surface is drawn translucently; other than eta1, eta2, eta3, its dimensions are taken at their first position.
titlestrNoneText in the scene’s corner. Default: "Marker orbits"; "" for none.
plotterpyvista.PlotterNoneDraw into this scene instead of a new one, to combine several views.

Returns

pyvista.Plotter
The plotter with the orbits, not yet shown.

Examples

>>> orbits.plasma.plot.orbits_3d(
... color_by="classification", domain=phi.isel(t=0)
... ).show()

pathsmethod#

def paths(x: str = 'x', y: str = 'y', markers=6, near=None, background: xr.DataArray | None = None, background_options: dict | None = None, t=0, ax=None, backend: Backend | None = None)

Plot the paths of a few markers in a plane, with start and end markers.

Optionally over a field (e.g. stream-function contour lines).

Parameters

NameTypeDefaultDescription
xstr'x'The quantity along the horizontal axis. Default: "x".
ystr'y'The quantity along the vertical axis. Default: "y".
markersint or sequence of int6A number of markers (spread evenly over the saved markers) or a list of marker indices. Default: 6.
nearsequence of (float, float)NonePicks instead the marker starting closest to each of a list of (x, y) points, e.g. a row across the domain.
backgroundxarray.DataArrayNoneA field drawn behind the paths at the time t: on its own x/y dimensions if it has them (a Cartesian field), in logical coordinates if x/y are eta1/eta2/eta3, else in the physical plane of x/y (the field then needs its X, Y, Z coordinates).
background_optionsdictNonePassed to [plot_slice()][plot_slice] for the background, e.g. dict(levels=12, fill=False) for the contour lines of a stream function.
tint or float0The time of the background: an integer position or a float value. Default: 0, the first.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn artists; data["markers"] holds the chosen markers.

Examples

>>> orbits.plasma.plot.paths(markers=4, background=psi.isel(t=0))

poincaremethod#

def poincare(coords: str = 'physical', color_by: str | None = 'line', s: float = 3.0, cmap=None, islands: bool = False, boundary: xr.DataArray | None = None, max_lines: int | None = None, ax=None, title: str | None = None, backend: Backend | None = None, **classification)

Plot the Poincaré section of these traced field lines.

Parameters

NameTypeDefaultDescription
coords('physical', 'logical')"physical"Draw R against z (physical), or the poloidal angle against the radial logical coordinate (logical). Default: "physical".
color_by('line', 'iota', 'classification', 'connection_length', None)"line"One color per line (cycling), a color bar over each line’s rotational transform or connection length, or the classes of classify_field_lines() (surface, island, chaotic) with a legend; None for one color. Default: "line".
sfloat3.0The marker size, in points². Default: 3.
cmapstr or matplotlib colormapNoneThe colormap of "iota" and "connection_length". Default: "viridis".
islandsboolFalseLabel the island chains with their n/m and widths. Default: False.
boundaryxarray.DataArrayNoneA field with physical coordinates whose outermost surface is drawn at the section (physical coordinates only).
max_linesintNoneDraw only the first max_lines lines. Default: all.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: the section’s label and angle.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**classification{}Options of classify_field_lines() (max_denominator, tolerance, threshold, min_spread), for color_by="classification" and islands_.

Returns

PlotResult
The figure, the axes and the scatters; data holds the section and, with islands, the chains and the classification.

Examples

>>> lines.plasma.plot.poincare(color_by="iota")
>>> lines.plasma.plot.poincare(color_by="classification", islands=True)

poloidalmethod#

def poloidal(color_by: str | None = 'classification', max_markers: int = 200, boundary: xr.DataArray | None = None, ax=None, backend: Backend | None = None)

Plot orbits projected onto the poloidal plane (R against z).

By default colored as passing, trapped or lost.

Parameters

NameTypeDefaultDescription
color_bystr or None'classification'"classification" colors by orbit class (needs v_par, see classify_orbits()); "t" or the name of a (t, marker) variable (e.g. "v_par") colors each orbit along its path, with a color bar; None gives one color per marker. Default: "classification".
max_markersint200Draw only the first max_markers markers. Default: 200.
boundaryxarray.DataArrayNoneAny field with physical coordinates, whose outer (last eta1) surface is drawn at its first eta3 as the domain boundary.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn lines.

Examples

>>> orbits.plasma.plot.poloidal(boundary=field)

power_spectrummethod#

def power_spectrum(backend: Backend | None = None, **options)

Plot the power of a time_fft Dataset.

Parameters

NameTypeDefaultDescription
**options{}The keyword options of plasma_plots.spectral_plots.plot_power_spectrum(), e.g. peaks=2.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and the drawn artists; data holds the averaged "power" and the found "peaks".

Examples

>>> phi.plasma.analysis.time_fft(detrend=True).plasma.plot.power_spectrum(
... peaks=2
... )

quantitiesmethod#

def quantities(quantities=('v_par', 'mu'), markers=6, drift_of=('mu'), backend: Backend | None = None)

Plot saved orbit quantities over time for a few markers.

E.g. v_par bouncing, or the drift of the invariant mu.

Parameters

NameTypeDefaultDescription
quantitiessequence of str('v_par', 'mu')The quantities, one panel each. Default: ("v_par", "mu").
markersint or sequence of int6A number of markers (spread over the classes if v_par is saved, so passing and trapped ones both show) or a list of marker indices. Default: 6.
drift_ofbool or sequence of str('mu')The quantities shown as their change since t = 0 (default ("mu",), an invariant of guiding-center motion, so its drift measures the pusher’s accuracy); True for all, False for none.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, one axes per quantity and the drawn lines.

Examples

>>> orbits.plasma.plot.quantities(markers=4)

scattermethod#

def scatter(x: str, y: str, color: str | None = None, ax=None, cmap=None, s: int = 8, color_at=None, background: xr.DataArray | None = None, background_options: dict | None = None, equal_aspect: bool | None = None, backend: Backend | None = None, **selection)

Scatter two marker variables, optionally colored by a third (e.g. density or a tracer).

Remaining dimensions such as t are selected by keyword, exactly like ArrayPlots.lineout(): an integer is a position (-1 the last), and a float is the nearest coordinate value. color_at colors by the values at another time (e.g. 0, the initial positions); background draws a field behind the markers.

Parameters

NameTypeDefaultDescription
xstrrequiredThe data variable along the horizontal axis, e.g. the position "x".
ystrrequiredThe data variable along the vertical axis, e.g. the position "y".
colorstrNoneA data variable to color the markers by, e.g. a Lagrangian tracer, weight or density, with a color bar. Default: one color.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
cmapstr or matplotlib.colors.ColormapNoneThe colormap for color. Default: "viridis".
sint8The marker size, in points². Default: 8.
color_atint or floatNoneTake the colors at another time (an integer position such as 0, or a float value), e.g. each marker’s initial position, to follow where fluid parcels go. Default: the selected time.
backgroundxarray.DataArrayNoneA field drawn behind the markers at the same time (select its other dimensions first): on its own x/y dimensions if it has them (a Cartesian field), in logical coordinates if x/y are eta1/eta2/eta3, else in the physical plane of x/y (x, y, z; the field then needs its X, Y, Z coordinates).
background_optionsdictNonePassed to [plot_slice()][plot_slice] for the background (e.g. cmap, levels, fill=False).
equal_aspectboolNoneDraw both axes to the same scale. Default: when x and y have the same units attribute (e.g. two positions), not for a phase space such as x against vx.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}The remaining dimensions, such as t, exactly like ArrayPlots.lineout(): an integer is a position (t=-1 the last), a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the drawn artists.

Examples

>>> markers.plasma.plot.scatter(x="x", y="y", color="density", t=-1)
>>> markers.plasma.plot.scatter(x="x", y="y", color="tracer", color_at=0, t=-1)

trajectoriesmethod#

def trajectories(max_markers: int = 200, show_paths: bool | None = None, ax=None, backend: Backend | None = None)

Plot the three-dimensional paths of saved markers, for an orbits product.

Parameters

NameTypeDefaultDescription
max_markersint200Draw only the first max_markers markers. Default: 200.
show_pathsboolNoneDraw each marker’s path, not only its last position. Default: True for up to 200 markers.
axmpl_toolkits.mplot3d.Axes3DNoneA 3-D axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the 3-D axes and the drawn artists.

Examples

>>> orbits.plasma.plot.trajectories(max_markers=200)

weight_histogrammethod#

def weight_histogram(weight: str = 'weight', t=-1, bins: int = 50, log: bool = True, density: bool = True, ax=None, title: str | None = None, backend: Backend | None = None)

Plot the distribution of the marker weights at one or several times.

Parameters

NameTypeDefaultDescription
weightstr'weight'The weight variable. Default: "weight".
t(int, float or sequence)-1The time(s): integer positions (-1 the last) or float nearest values, one or several. Default: -1.
binsint50The number of bins, shared by all times. Default: 50.
logboolTrueA logarithmic count axis. Default: True.
densityboolTrueNormalize each histogram to unit area. Default: True.
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
titlestrNoneThe title. Default: the noise estimate at the last time shown.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the axes and one outline per time; data["statistics"].

Examples

>>> orbits.plasma.plot.weight_histogram(t=[0, 0.5, -1])

PlasmaAccessorclass#

class PlasmaAccessor(array: xr.DataArray)

Struphy diagnostics of one array: array.plasma.plot, .analysis and .data.

Registered on every xarray.DataArray when plasma_plots is imported. A GVEC evaluation is read in plasma-plots’ conventions first (see plasma_plots.gvec.from_gvec()).

Examples

>>> import plasma_plots
>>> phi.plasma.plot.slice(x="eta1", y="eta2", t=-1)

analysisproperty#

analysis: 'ArrayAnalysis'

Diagnostics of this array, e.g. array.plasma.analysis.growth_rate().

dataproperty#

data: 'ArrayData'

The data behind each plot, without rendering it.

E.g. for a different plotting library: array.plasma.data.slice(x="eta1", y="v1", t=-1).

plotproperty#

plot: 'ArrayPlots'

Plots of this array, e.g. array.plasma.plot.slice(x="eta1", y="v1", t=-1).

PlasmaDatasetAccessorclass#

class PlasmaDatasetAccessor(dataset: xr.Dataset)

Struphy diagnostics of one dataset, e.g. an orbits product: dataset.plasma.plot.

Also dataset.plasma.analysis and dataset.plasma.data. Registered on every xarray.Dataset when plasma_plots is imported. A GVEC evaluation is read in plasma-plots’ conventions first (see plasma_plots.gvec.from_gvec()).

Examples

>>> orbits.plasma.plot.trajectories()
>>> orbits.plasma.analysis.classify_orbits()

analysisproperty#

analysis: 'DatasetAnalysis'

Diagnostics of this dataset, e.g. orbits.plasma.analysis.classify_orbits().

dataproperty#

data: 'DatasetData'

The data behind each plot, without rendering it: orbits.plasma.data.scatter(...).

plotproperty#

plot: 'DatasetPlots'

Plots of this dataset, e.g. orbits.plasma.plot.trajectories().

SliceViewclass#

class SliceView(array, coordinates, selection, options)

A configured array view, shared by static, interactive and exported plots.

Construct with array.plasma.plot.view(...) (ArrayPlots.view()), which sets its selection and rendering options. Configuration does not create figures or copy the underlying array.

Examples

>>> view = phi.plasma.plot.view(
... x="eta1", y="eta2", cmap="RdBu_r", symmetric=True
... )
>>> view.slice(t=-1)
>>> view.animation(step=2)

animationmethod#

def animation(interval=100, step=1, max_frames=None, alongside=None, backend: Backend | None = None)

Create a Matplotlib animation using this view’s rendering options.

Keep a reference to the returned animation.

Parameters

NameTypeDefaultDescription
intervalint100The delay between frames, in milliseconds. Default: 100.
stepint1Use every step-th value of the sweep. Default: 1.
max_framesintNoneKeep at most this many frames, evenly spaced over those step leaves (the first and last included), e.g. to keep a Plotly animation small. Default: all.
alongsidelist of xarray.DataArrayNoneFurther arrays with the same dimensions, animated side by side in sync, each with its own color limits.
backend('matplotlib', 'plotly')"matplotlib"Draw with Matplotlib, or as an interactive Plotly figure with a slider (in result.fig; needs plotly, see plasma_plots.plotly_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

matplotlib.animation.FuncAnimation or PlotResult
The animation; with backend="plotly" a result whose Plotly figure has a slider and Play/Pause buttons.

Examples

>>> view.animation(step=2)

panelsmethod#

def panels(nrows=3, ncols=4, backend: Backend | None = None)

Draw snapshots spread evenly along the sweep.

Parameters

NameTypeDefaultDescription
nrowsint3The number of rows of panels. Default: 3.
ncolsint4The number of columns of panels. Default: 4.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

PlotResult
The figure, the array of axes and the drawn meshes.

Examples

>>> view.panels(nrows=2, ncols=3)

save_framesmethod#

def save_frames(directory, *, step=1, prefix='frame', dpi=110)

Export PNG frames using this view’s rendering options.

Parameters

NameTypeDefaultDescription
directorystr or pathlib.PathrequiredThe directory to write into.
stepint1Use every step-th value of the sweep. Default: 1.
prefixstr'frame'The start of each file name. Default: "frame".
dpiint110The resolution of the PNGs. Default: 110.

Returns

list of str
The paths of the written files.

Examples

>>> view.save_frames("frames")

slicemethod#

def slice(ax=None, backend: Backend | None = None, **selection)

Draw a snapshot, e.g. view.slice(t=-1).

With shared_clim, the color limits come from all of the view’s data, so the snapshot uses the same scale as its panels, animation and exported frames.

Parameters

NameTypeDefaultDescription
axmatplotlib.axes.AxesNoneThe axes to draw into. Default: a new figure.
backend('matplotlib', 'plotly', 'tikz')"matplotlib"Draw with Matplotlib, as an interactive Plotly figure, or as TikZ/pgfplots code for LaTeX (in result.fig; needs plotly or maxplotlib, see plasma_plots.plotly_backend and plasma_plots.tikz_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.
**selection{}Further dimensions to select, e.g. t=-1, in addition to (or overriding) the view’s own selection: an integer is a position, a float the nearest coordinate value.

Returns

PlotResult
The figure, the axes and the drawn mesh.

Examples

>>> view.slice(t=-1)

viewermethod#

def viewer(backend: Backend | None = None)

Create a viewer with sliders for the unselected dimensions.

Keep a reference to the returned viewer.

Parameters

NameTypeDefaultDescription
backend('matplotlib', 'plotly')"matplotlib"Draw with Matplotlib, or as an interactive Plotly figure with a slider (in result.fig; needs plotly, see plasma_plots.plotly_backend). Default: the one set with plasma_plots.set_backend(), "matplotlib" unless changed.

Returns

plasma_plots.plotting.InteractiveSliceViewer or PlotResult
The viewer, with this view’s rendering options; with backend="plotly" a result whose Plotly figure has one slider (one unselected dimension at most).