Plotting (esc_etc.plotting)

Lazuli-styled matplotlib plotting helpers for the ESC ETC.

Mirrors wcc-etc’s plotting.py conventions: each helper takes the domain object (Simulation/Coronagraph/Sensor/Scene) positionally OR explicit raw arrays as keywords, accepts ax=None, applies the lazuli style via a context manager, and returns (fig, ax). The style ships as data/lazuli.mplstyle (byte-identical to the canonical lazuli-transit copy).

esc_etc.plotting.lazuli_style()[source]

Context manager applying the lazuli style without touching global rcParams, except that interactive mode switched on inside the block (Jupyter’s inline backend does this on the first figure) stays on.

Usage: with lazuli_style(): .... Every helper wraps its drawing in this.

esc_etc.plotting.use_lazuli_style()[source]

Apply the lazuli style to matplotlib’s global rcParams (opt-in, mutates state).

esc_etc.plotting.plot_count_rates(sim=None, *, rates=None, sensor=None, ax=None, log=True)[source]

Bar chart of count-rate contributors (e-/s): source, zodi, exozodi, speckle, and dark-current total (dark_current * num_psf_pixels).

Pass a Simulation, or explicit rates (CountRates) + sensor. Returns (fig, ax).

esc_etc.plotting.plot_snr_vs_time(sim=None, *, total_times=None, frame_time=None, snrs=None, sweep=None, label=None, ax=None)[source]

SNR vs total integration time (log-log).

Pass a Simulation (sweeps total_times, default logspace from one frame to 1e5 s, computing SNR per point via the engine’s noise_model with a single count-rate evaluation), or explicit (total_times, snrs). frame_time defaults to 100 s.

sweep={"coronagraph__raw_dh_contrast": [1e-7, 1e-8, 1e-9]} draws one curve per value of one update-style parameter (any nesting, e.g. "scene__zodi__mag") and puts the original value back afterwards. label names the single curve (for a legend when drawing several onto one ax). Returns (fig, ax).

esc_etc.plotting.plot_offaxis_throughput(coronagraph=None, *, separations=None, throughputs=None, label=None, ax=None, mark_separation=True)[source]

Coronagraph off-axis (FPM) throughput vs planet separation (arcsec).

Pass a Coronagraph, a Simulation (uses .coronagraph), or explicit (separations, throughputs). When mark_separation, draws a vertical marker at the coronagraph’s current separation. Returns (fig, ax).

esc_etc.plotting.plot_bandpass(sensor=None, *, wavelength=None, throughput=None, label=None, ax=None)[source]

Instrument bandpass throughput vs wavelength (nm).

Pass a Sensor, a Simulation (uses .sensor), or explicit (wavelength, throughput). wavelength may be an astropy Quantity (converted to nm) or a plain array (nm). Returns (fig, ax).

esc_etc.plotting.plot_spectra(scene=None, *, which=('star', 'planet', 'zodi'), ax=None)[source]

Scene element spectra over 3000-9000 Angstrom.

Pass a Scene or a Simulation (uses .scene). which names the elements to draw. Returns (fig, ax).

esc_etc.plotting.plot_aperture(sensor=None, *, ax=None, half_lamD=2.5)[source]

The noise/extraction aperture drawn over a pixel-integrated Airy PSF.

Pass a Sensor or a Simulation (uses .sensor). Shows the footprint that the SNR terms use: a disk for “resel”/”optimal”, the n x n square for “box”, and for “matched” a dashed circle of the equivalent area N_eff (there is no hard edge; every pixel is weighted). Axes are in detector pixels. Returns (fig, ax).

esc_etc.plotting.plot_overview(sim=None, *, frame_time=None, axes=None)[source]

2 x 3 overview of a Simulation: count rates, SNR vs time, bandpass; off-axis throughput, aperture footprint, scene spectra.

axes may be an existing 2 x 3 array of axes. Returns (fig, axes).