Skip to content

Plotting

blipss.plotting.plots

Plotting utilities for BLIPSS candidate visualization and diagnostic plots.

candverf_plot(period, bins, detrended_ts, periodograms, annotations, start_mjds, max_snr, periodaxis_log, plot_name, output_formats, use_latex=False)

Multi-row candidate verification plot combining periodogram, pulse profile, and phase-time diagram.

Each row corresponds to one data file. Left panel: periodogram with a dashed vertical line at the candidate period. Top-right panel: normalized average pulse profile. Bottom-right panel: phase-time diagram with flux density on a grayscale.

Parameters:

Name Type Description Default
period float

Candidate folding period (s)

required
bins int

Number of phase bins in the folded profile

required
detrended_ts Sequence[Any]

Riptide TimeSeries objects, one per data file

required
periodograms Sequence[Any]

Riptide Periodogram objects, one per data file

required
annotations Sequence[str]

Custom text annotations for each row (e.g., beam or ON/OFF labels)

required
start_mjds Sequence[float]

Start MJDs (UTC) for each data file

required
max_snr float

Maximum S/N value shown on the periodogram y-axis

required
periodaxis_log bool

Whether to use a logarithmic period axis

required
plot_name str

Output file path without extension

required
output_formats Sequence[str]

File extensions (with leading dot) for each output format

required
use_latex bool

Render text with LaTeX (requires a system LaTeX installation); defaults to False

False
Source code in blipss/plotting/plots.py
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
def candverf_plot(
    period: float,
    bins: int,
    detrended_ts: Sequence[Any],
    periodograms: Sequence[Any],
    annotations: Sequence[str],
    start_mjds: Sequence[float],
    max_snr: float,
    periodaxis_log: bool,
    plot_name: str,
    output_formats: Sequence[str],
    use_latex: bool = False,
) -> None:
    """
    Multi-row candidate verification plot combining periodogram, pulse profile, and phase-time diagram.

    Each row corresponds to one data file. Left panel: periodogram with a dashed vertical
    line at the candidate period. Top-right panel: normalized average pulse profile.
    Bottom-right panel: phase-time diagram with flux density on a grayscale.

    Args:
        period: Candidate folding period (s)
        bins: Number of phase bins in the folded profile
        detrended_ts: Riptide TimeSeries objects, one per data file
        periodograms: Riptide Periodogram objects, one per data file
        annotations: Custom text annotations for each row (e.g., beam or ON/OFF labels)
        start_mjds: Start MJDs (UTC) for each data file
        max_snr: Maximum S/N value shown on the periodogram y-axis
        periodaxis_log: Whether to use a logarithmic period axis
        plot_name: Output file path without extension
        output_formats: File extensions (with leading dot) for each output format
        use_latex: Render text with LaTeX (requires a system LaTeX installation); defaults to False
    """
    if use_latex:
        _require_latex()
    rc = {"text.usetex": True, "text.latex.preamble": r"\usepackage{amsmath}"} if use_latex else {}
    with mpl.rc_context(rc):
        n_datafiles = len(detrended_ts)
        fig = plt.figure(figsize=(12, 14))
        outer = gridspec.GridSpec(n_datafiles, 2, figure=fig, height_ratios=list(np.ones(n_datafiles)))
        phasebin_centers = _phasebin_centers(bins)
        for j in range(n_datafiles):
            gs1 = gridspec.GridSpecFromSubplotSpec(1, 1, subplot_spec=outer[j, 0])
            ax1 = plt.subplot(gs1[0])
            _configure_periodogram_ax(
                ax1,
                periodograms[j].periods,
                periodograms[j].snrs.max(axis=1),
                annotations[j],
                start_mjds[j],
                period,
                max_snr,
                periodaxis_log,
            )

            phase_time, profile = _fold_and_normalize(detrended_ts[j], period, bins)

            gs2 = gridspec.GridSpecFromSubplotSpec(2, 1, subplot_spec=outer[j, 1], height_ratios=[1, 1], hspace=0)
            ax20 = plt.subplot(gs2[0])
            _plot_avg_profile_ax(ax20, phasebin_centers, profile)

            ax21 = plt.subplot(gs2[1], sharex=ax20)
            _plot_phase_time_ax(ax21, phase_time, phasebin_centers, period)

            _apply_row_x_labels(ax1, ax20, ax21, is_last_row=(j == n_datafiles - 1))

        fig.subplots_adjust(left=0.07, right=0.98, bottom=0.07, top=0.98, hspace=0.1, wspace=0.2)
        fig.text(0.013, 0.55, "Matched filtering S/N", va="center", rotation="vertical", fontsize=LABEL_FONTSIZE)
        _save_and_close(plot_name, output_formats)

plot_phase_resolved_dynamic_spectrum(phaseresolved_ds, freqs_MHz, period, start_mjd, plot_name, plot_formats, use_latex=False)

Produce a grayscale imshow plot of a phase-resolved dynamic spectrum.

The figure has four panels: frequency-averaged profile (top-left), blank annotation panel (top-right), phase-resolved spectrum (bottom-left), and time-averaged band spectrum (bottom-right).

Parameters:

Name Type Description Default
phaseresolved_ds NDArray[floating]

2D data array of shape (n_chans, n_bins)

required
freqs_MHz NDArray[floating]

Radio frequencies (MHz) corresponding to each channel

required
period float

Folding period (s)

required
start_mjd float

Start MJD (UTC) of the observation

required
plot_name str

Output file path without extension

required
plot_formats Sequence[str]

File extensions (with leading dot) for each output format

required
use_latex bool

Render text with LaTeX (requires a system LaTeX installation); defaults to False

False
Source code in blipss/plotting/plots.py
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
def plot_phase_resolved_dynamic_spectrum(
    phaseresolved_ds: npt.NDArray[np.floating],
    freqs_MHz: npt.NDArray[np.floating],
    period: float,
    start_mjd: float,
    plot_name: str,
    plot_formats: Sequence[str],
    use_latex: bool = False,
) -> None:
    """
    Produce a grayscale imshow plot of a phase-resolved dynamic spectrum.

    The figure has four panels: frequency-averaged profile (top-left), blank annotation
    panel (top-right), phase-resolved spectrum (bottom-left), and time-averaged band
    spectrum (bottom-right).

    Args:
        phaseresolved_ds: 2D data array of shape (n_chans, n_bins)
        freqs_MHz: Radio frequencies (MHz) corresponding to each channel
        period: Folding period (s)
        start_mjd: Start MJD (UTC) of the observation
        plot_name: Output file path without extension
        plot_formats: File extensions (with leading dot) for each output format
        use_latex: Render text with LaTeX (requires a system LaTeX installation); defaults to False
    """
    if use_latex:
        _require_latex()
    rc = {"text.usetex": True, "text.latex.preamble": r"\usepackage{amsmath}"} if use_latex else {}
    with mpl.rc_context(rc):
        bins = len(phaseresolved_ds[0])
        phasebin_centers = _phasebin_centers(bins)
        _, axes = plt.subplots(
            nrows=2,
            ncols=2,
            figsize=(8, 7),
            constrained_layout=True,
            gridspec_kw={"height_ratios": [1, 3], "width_ratios": [3, 1]},
        )
        axes[0, 1].axis("off")
        _plot_freq_averaged_profile(axes[0, 0], phasebin_centers, phaseresolved_ds)
        _plot_phase_resolved_spectrum(axes[1, 0], phaseresolved_ds, phasebin_centers, freqs_MHz, start_mjd)
        _plot_band_averaged_spectrum(axes[1, 1], phaseresolved_ds, freqs_MHz)
        _annotate_period_bins(axes[0, 1], period, bins)
        _save_and_close(plot_name, plot_formats)

scatterplot_period_radiofreq(cand_periods, cand_freqs, cand_snrs, cand_flags, basename, min_period, max_period, min_freq, max_freq, plot_formats=None, use_latex=False)

Produce a scatter plot of periodicity detections in the radio-frequency vs. trial-period plane.

Candidate S/N values are shown on a color scale. Fundamental frequencies use a circular marker, sub-harmonics a plus symbol, and harmonics a cross symbol.

Parameters:

Name Type Description Default
cand_periods NDArray[floating]

Trial periods (s) of detected signals

required
cand_freqs NDArray[floating]

Radio frequencies (MHz) corresponding to candidate detections

required
cand_snrs NDArray[floating]

Matched-filtering S/N values of detected candidates

required
cand_flags NDArray[str_]

Harmonic flags ('F', 'S', or 'H') assigned to each candidate

required
basename str

Output plot basename including output path (no extension)

required
min_period float

Minimum trial period (s) shown on the x-axis

required
max_period float

Maximum trial period (s) shown on the x-axis

required
min_freq float

Minimum radio frequency (MHz) on the y-axis

required
max_freq float

Maximum radio frequency (MHz) on the y-axis

required
plot_formats Sequence[str] | None

File extensions (with leading dot) for saving the plot; defaults to ['.png']

None
use_latex bool

Render text with LaTeX (requires a system LaTeX installation); defaults to False

False
Source code in blipss/plotting/plots.py
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
def scatterplot_period_radiofreq(
    cand_periods: npt.NDArray[np.floating],
    cand_freqs: npt.NDArray[np.floating],
    cand_snrs: npt.NDArray[np.floating],
    cand_flags: npt.NDArray[np.str_],
    basename: str,
    min_period: float,
    max_period: float,
    min_freq: float,
    max_freq: float,
    plot_formats: Sequence[str] | None = None,
    use_latex: bool = False,
) -> None:
    """
    Produce a scatter plot of periodicity detections in the radio-frequency vs. trial-period plane.

    Candidate S/N values are shown on a color scale. Fundamental frequencies use a circular
    marker, sub-harmonics a plus symbol, and harmonics a cross symbol.

    Args:
        cand_periods: Trial periods (s) of detected signals
        cand_freqs: Radio frequencies (MHz) corresponding to candidate detections
        cand_snrs: Matched-filtering S/N values of detected candidates
        cand_flags: Harmonic flags ('F', 'S', or 'H') assigned to each candidate
        basename: Output plot basename including output path (no extension)
        min_period: Minimum trial period (s) shown on the x-axis
        max_period: Maximum trial period (s) shown on the x-axis
        min_freq: Minimum radio frequency (MHz) on the y-axis
        max_freq: Maximum radio frequency (MHz) on the y-axis
        plot_formats: File extensions (with leading dot) for saving the plot; defaults to ['.png']
        use_latex: Render text with LaTeX (requires a system LaTeX installation); defaults to False
    """
    if use_latex:
        _require_latex()
    if plot_formats is None:
        plot_formats = [".png"]
    rc = {"text.usetex": True, "text.latex.preamble": r"\usepackage{amsmath}"} if use_latex else {}
    with mpl.rc_context(rc):
        cmap, norm = _make_snr_norm(cand_snrs)
        plt.figure(figsize=(7, 6))
        marker_count = 0
        for flag, marker, label in [
            (FUNDAMENTAL_FLAG, "o", "Fundamental"),
            (SUBHARMONIC_FLAG, "+", "Subharmonic"),
            (HARMONIC_FLAG, "x", "Harmonic"),
        ]:
            if _scatter_candidate_group(
                cand_periods, cand_freqs, cand_snrs, cand_flags, flag, marker, label, cmap, norm
            ):
                marker_count += 1
        _add_snr_colorbar(cmap, norm, plt.gca())
        _configure_scatter_axes(min_period, max_period, min_freq, max_freq)
        _add_candidate_legend(marker_count)
        plt.tight_layout()
        _save_and_close(basename, plot_formats)