magnus.plotting
Pre-packaged figures for Mag \(\nu\) s.
Every figure in notebooks/ used to be built by hand: roughly 25–40 lines of
gridspec_kw, tick locators, legend keywords and savefig per plot,
copy-pasted and lightly varied. This module collapses that into one call per
figure while reproducing the same output, so that switching an existing figure
over to it leaves the figure unchanged.
Taking stock of the fifty-odd figures showed that most of them are the same
figure with different data. Curves against baseline, curves against energy,
curves against a mixing angle, and the convergence studies of the
matrix-exponential notebook all share one shape: a set of curves plotted
against a swept variable, optionally over a short relative-error subpanel.
plot_curves() is that shape, and the plot_probability_vs_* helpers
are thin wrappers that only preset labels and limits.
plot_curves_stacked() is its small-multiples form: the same plot repeated
once per case down a shared abscissa, where the comparison is between panels.
The genuinely distinct layouts are the profile-plus-probability stack, the
bi-probability plane, and the oscillogram.
API conventions
The functions take named arguments for the quantities every figure has
(data, labels, limits, scales, ticks, title, legend placement, output path) and
explicit pass-through dictionaries for the long tail of Matplotlib
settings: legend_kw, grid_kw, savefig_kw, subplots_kw, and per
curve any Line2D keyword.
There is deliberately no bare **kwargs on any of these functions. A
catch-all signature accepts a misspelled keyword in silence, and this project
has already paid for that once: oscprob’s keyword chain forwarded unknown
names down several layers before failing somewhere unrecognisable, which is why
magnus.oscprob.osc_prob() now raises on stray keys. Here every keyword is
either named in the signature – so a typo is a TypeError at the call
site – or lands in a dictionary destined for one specific Matplotlib call –
so a typo is an error from that call, naming the offending key. Nothing is
swallowed.
Styling that is global (fonts, tick sizes and directions, LaTeX rendering)
belongs to notebooks/matplotlibrc and is deliberately not set here; the
defaults below cover only what the notebooks were overriding per figure.
All functions return (fig, ax) so that the caller can keep customising:
fig for figure-level work and saving, ax for anything Matplotlib
exposes on an axes.
Requirements
Matplotlib ships with Magνs, so this module is available in any installation and needs nothing extra.
Added in version 1.0.0.
Attributes
Default figure size, in inches, used throughout the notebooks. |
|
Height of the relative-error subpanel, relative to the main panel. |
|
Legend keywords repeated verbatim on essentially every notebook figure. |
|
Grid keywords used by the notebooks. |
|
Default |
Exceptions
Raised when |
Functions
|
Return the LaTeX label for an oscillation probability. |
|
Plot a set of curves against a swept variable, with an optional error subpanel. |
|
Plot small multiples: one panel per case, stacked over a shared abscissa. |
|
Plot oscillation probabilities against baseline. |
|
Plot oscillation probabilities against neutrino energy. |
|
Stack a matter-density panel above one or more probability panels. |
|
Overlay phase-averaged probabilities on the oscillating ones. |
|
Plot neutrino against antineutrino appearance probability. |
|
Plot an oscillogram: probability over zenith angle and energy. |
Module Contents
- exception magnus.plotting.MatplotlibNotFoundError[source]
Bases:
ImportErrorRaised when
magnus.plottingis used without Matplotlib installed.Added in version 1.0.0.
- magnus.plotting.HOUSE_FIGSIZE: Tuple[float, float] = (18.0, 9.0)[source]
Default figure size, in inches, used throughout the notebooks.
Added in version 1.0.0.
- magnus.plotting.HOUSE_RESIDUAL_HEIGHT: float = 0.3[source]
Height of the relative-error subpanel, relative to the main panel.
Added in version 1.0.0.
- magnus.plotting.HOUSE_LEGEND_KW: Dict[str, Any][source]
Legend keywords repeated verbatim on essentially every notebook figure.
Added in version 1.0.0.
- magnus.plotting.HOUSE_GRID_KW: Dict[str, Any][source]
Grid keywords used by the notebooks.
Added in version 1.0.0.
- magnus.plotting.HOUSE_SAVEFIG_KW: Dict[str, Any][source]
Default
savefig()keywords; figures go to../fig/as PDF.Added in version 1.0.0.
- magnus.plotting.prob_label(nu_i: int, nu_f: int, nubar: bool | None = False) str[source]
Return the LaTeX label for an oscillation probability.
A
prob_labelhelper was defined separately in several notebooks, with hand-writtenif/elifchains covering only the three active flavours. This version also covers the sterile states, so the sterile-neutrino notebook can use it too.Added in version 1.0.0.
- Parameters:
- Returns:
A LaTeX string such as
'$P_{\\nu_e \\to \\nu_\\mu}$'.- Return type:
- Raises:
ValueError – If either flavour index is not one of the known values.
Examples
import magnus.globaldefs as gd from magnus.plotting import prob_label print(prob_label(gd.NUMU, gd.NUE)) print(prob_label(gd.NUMU, gd.NUE, nubar=True))
$P_{\nu_\mu \to \nu_e}$ $P_{\bar{\nu}_\mu \to \bar{\nu}_e}$
- magnus.plotting.plot_curves(x: Sequence[float], curves: Sequence[Sequence[float] | Dict[str, Any]], *, xlabel: str | None = None, ylabel: str | None = None, title: str | None = None, xlim: Tuple[float, float] | None = None, ylim: Tuple[float, float] | None = None, xscale: str = 'linear', yscale: str = 'linear', xmajor: float | None = None, xminor: float | None = None, ymajor: float | None = None, yminor: float | None = None, residual: Sequence[float] | None = None, residual_label: str | None = None, residual_ylim: Tuple[float, float] | None = None, residual_ymajor: float | None = None, residual_yminor: float | None = None, residual_height: float = HOUSE_RESIDUAL_HEIGHT, residual_kw: Dict[str, Any] | None = None, annotations: Sequence[Dict[str, Any]] | None = None, legend: bool = True, legend_title: str | None = None, legend_loc: str | None = None, legend_kw: Dict[str, Any] | None = None, grid: bool = False, grid_kw: Dict[str, Any] | None = None, ylabel_labelpad: float = 25.0, title_fontsize: float = 20.0, figsize: Tuple[float, float] = HOUSE_FIGSIZE, subplots_kw: Dict[str, Any] | None = None, savefig: str | None = None, savefig_kw: Dict[str, Any] | None = None, tight_layout: bool = True)[source]
Plot a set of curves against a swept variable, with an optional error subpanel.
This is the workhorse: most notebook figures are an instance of it. The
plot_probability_vs_baselineandplot_probability_vs_energywrappers differ from it only in their preset labels and limits, and the convergence studies of the matrix-exponential notebook use it directly with a slab count or grid size on the abscissa.Added in version 1.0.0.
- Parameters:
x (sequence of float) – Abscissa, shared by every curve and by the residual panel.
curves (sequence) – One entry per curve. An entry is either a bare ordinate array, or a dict carrying the ordinate under
'y'plus anyLine2Dkeyword (label,color,ls,lw, …). Entries without an explicit colour take the'C0','C1', … cycle in order.xlabel (str, optional) – Axis labels and title.
ylabelgoes on the main panel.ylabel (str, optional) – Axis labels and title.
ylabelgoes on the main panel.title (str, optional) – Axis labels and title.
ylabelgoes on the main panel.xlim (tuple of float, optional) – Axis limits.
xlimis applied to the residual panel too, so the two panels stay aligned.ylim (tuple of float, optional) – Axis limits.
xlimis applied to the residual panel too, so the two panels stay aligned.xscale (str, optional) – Matplotlib axis scales, e.g.
'log'. Default is'linear'.xscaleis applied to the residual panel as well.yscale (str, optional) – Matplotlib axis scales, e.g.
'log'. Default is'linear'.xscaleis applied to the residual panel as well.xmajor (float, optional) – Major/minor tick spacings for the main panel.
xminor (float, optional) – Major/minor tick spacings for the main panel.
ymajor (float, optional) – Major/minor tick spacings for the main panel.
yminor (float, optional) – Major/minor tick spacings for the main panel.
residual (sequence of float, optional) – If given, a short subpanel is added below the main panel and this is plotted in it – typically a relative error against a reference curve. The main panel’s tick labels are then suppressed, as in the notebooks.
residual_label (str, optional) – Ordinate label for the residual subpanel.
residual_ylim (tuple of float, optional) – Ordinate limits for the residual subpanel.
residual_ymajor (float, optional) – Tick spacings for the residual subpanel.
residual_yminor (float, optional) – Tick spacings for the residual subpanel.
residual_height (float, optional) – Height of the residual subpanel relative to the main panel. Default is
HOUSE_RESIDUAL_HEIGHT.residual_kw (dict, optional) – Extra
Line2Dkeywords for the residual curve. Defaults to a thin black solid line.annotations (sequence of dict, optional) – Text placed on the main panel. Each entry needs
'text'and'xy'(axes fractions by default) and may carry any otherannotate()keyword. Used by the BSM notebooks to record the parameter values a figure was made with.legend (bool, optional) – Whether to draw a legend. Default is
True; it is drawn only if at least one curve carries alabel.legend_title (str, optional) – Legend title.
legend_loc (str, optional) – Legend location.
legend_kw (dict, optional) – Extra keywords merged over
HOUSE_LEGEND_KWand forwarded tolegend().grid (bool, optional) – Whether to draw a grid. Default is
False.grid_kw (dict, optional) – Extra keywords merged over
HOUSE_GRID_KW.ylabel_labelpad (float, optional) – Padding of the main ordinate label. Default is
25.0.title_fontsize (float, optional) – Title font size. Default is
20.0.figsize (tuple of float, optional) – Figure size in inches. Default is
HOUSE_FIGSIZE.subplots_kw (dict, optional) – Extra keywords for
subplots().savefig (str, optional) – If given, the figure is written here.
savefig_kw (dict, optional) – Extra keywords merged over
HOUSE_SAVEFIG_KW.tight_layout (bool, optional) – Whether to call
tight_layout(). Default isTrue.
- Returns:
fig (matplotlib.figure.Figure) – The figure, ready for further customisation or saving.
ax (matplotlib.axes.Axes or numpy.ndarray of Axes) – A single axes when there is no residual panel; an array of two (main, residual) when there is.
Examples
import matplotlib matplotlib.use('Agg') import numpy as np from magnus.plotting import plot_curves # starts away from zero: the reference appears in a denominator below, # and sin(0)**2 is exactly 0 L = np.linspace(50.0, 1000.0, 200) exact = np.sin(L / 200.0) ** 2 approx = exact + 1e-3 * np.cos(L / 50.0) fig, ax = plot_curves( L, [dict(y=approx, label='Magnus expansion', color='C1'), dict(y=exact, label='Standard formula', color='k', ls='--')], xlabel=r'Baseline, $L$ [km]', ylabel='Probability', ylim=(0, 1), residual=(approx - exact) / exact, residual_label=r'$\epsilon_{\rm rel}$', legend_title='Method', ) print(len(ax), ax[0].get_ylim())
2 (np.float64(0.0), np.float64(1.0))
- magnus.plotting.plot_curves_stacked(x: Sequence[float], panels: Sequence[Sequence[Sequence[float] | Dict[str, Any]]], *, xlabel: str | None = None, ylabel: str | None = None, title: str | None = None, xlim: Tuple[float, float] | None = None, ylim: Tuple[float, float] | None = None, xscale: str = 'linear', yscale: str = 'linear', xmajor: float | None = None, xminor: float | None = None, ymajor: float | None = None, yminor: float | None = None, panel_labels: Sequence[str] | None = None, panel_label_xy: Tuple[float, float] = (0.02, 0.1), panel_label_kw: Dict[str, Any] | None = None, annotations: Sequence[Dict[str, Any]] | None = None, legend: bool = True, legend_panel: int = 0, legend_proxies: Sequence[Dict[str, Any]] | None = None, legend_title: str | None = None, legend_loc: str | None = None, legend_kw: Dict[str, Any] | None = None, grid: bool = False, grid_kw: Dict[str, Any] | None = None, ylabel_kw: Dict[str, Any] | None = None, title_fontsize: float = 23.0, figsize: Tuple[float, float] | None = None, height_ratios: Sequence[float] | None = None, subplots_kw: Dict[str, Any] | None = None, savefig: str | None = None, savefig_kw: Dict[str, Any] | None = None, tight_layout: bool = True)[source]
Plot small multiples: one panel per case, stacked over a shared abscissa.
The layout for “the same quantity, once per configuration” – one panel per detector, per baseline, per zenith angle – where the comparison the reader makes is between panels, so every panel must share limits, scales and tick spacings exactly. Only the bottom panel keeps its tick labels and abscissa label, and the ordinate label is a single figure-level label spanning the stack.
This differs from
plot_probability_with_profile(), whose panels show different quantities (a density profile above a probability), and fromplot_curves(), whose optional second panel is a relative error rather than another instance of the same plot.Added in version 1.0.0.
- Parameters:
x (sequence of float) – Abscissa, shared by every panel.
panels (sequence of sequence) – One entry per panel, each a sequence of curves in the form
plot_curves()accepts: a bare ordinate array, or a dict carrying the ordinate under'y'plus anyLine2Dkeyword. Curves without an explicit colour take the'C0','C1', … cycle within their panel, so the n-th curve of every panel matches by default.xlabel (str, optional) – Abscissa label, placed on the bottom panel only.
ylabel (str, optional) – Ordinate label. Drawn once for the whole stack with
supylabel(), since every panel shows the same quantity. Being figure-level, it takes nolabelpad; useylabel_kwfor its placement.title (str, optional) – Title, placed above the top panel.
xlim (tuple of float, optional) – Axis limits, applied to every panel.
ylim (tuple of float, optional) – Axis limits, applied to every panel.
xscale (str, optional) – Matplotlib axis scales, applied to every panel. Default
'linear'.yscale (str, optional) – Matplotlib axis scales, applied to every panel. Default
'linear'.xmajor (float, optional) – Major/minor tick spacings, applied to every panel.
xminor (float, optional) – Major/minor tick spacings, applied to every panel.
ymajor (float, optional) – Major/minor tick spacings, applied to every panel.
yminor (float, optional) – Major/minor tick spacings, applied to every panel.
panel_labels (sequence of str, optional) – One caption per panel, annotated inside it – the usual way of saying which case a panel is. Must match the number of panels.
panel_label_xy (tuple of float, optional) – Position of those captions, in axes fractions. Default
(0.02, 0.10).panel_label_kw (dict, optional) – Extra
annotate()keywords for them.annotations (sequence of dict, optional) – Free-form text. Each entry needs
'text'and'xy', may name a'panel'(index, default 0), and may carry any otherannotate()keyword.legend (bool, optional) – Whether to draw a legend. Default
True; drawn only if there is something to put in it.legend_panel (int, optional) – Which panel carries the legend. Default
0.legend_proxies (sequence of dict, optional) – Legend entries that describe a style shared across panels rather than any one curve – e.g. “solid: 3+1, dashed: standard” when the colour varies from panel to panel. Each entry is a set of
Line2Dkeywords includinglabel, drawn as an empty proxy artist. When given, these replace the labels picked up from the curves themselves. This exists because the alternative, and what the notebooks did, is plotting dummy points outside the axis limits to manufacture legend handles.legend_title (str, optional) – Legend title and location.
legend_loc (str, optional) – Legend title and location.
legend_kw (dict, optional) – Extra keywords merged over
HOUSE_LEGEND_KW.grid (bool, optional) – Whether to draw a grid on every panel. Default
False.grid_kw (dict, optional) – Extra keywords merged over
HOUSE_GRID_KW.ylabel_kw (dict, optional) – Extra keywords for
supylabel().title_fontsize (float, optional) – Title font size. Default
23.0.figsize (tuple of float, optional) – Figure size in inches. Defaults to
HOUSE_FIGSIZE’s width and half its height per panel, which reproduces the notebooks’ proportions.height_ratios (sequence of float, optional) – Relative panel heights. Default: equal.
subplots_kw (dict, optional) – Extra keywords for
subplots().savefig (str, optional) – If given, the figure is written here.
savefig_kw (dict, optional) – Extra keywords merged over
HOUSE_SAVEFIG_KW.tight_layout (bool, optional) – Whether to call
tight_layout(). DefaultTrue.
- Returns:
fig (matplotlib.figure.Figure) – The figure, ready for further customisation or saving.
ax (numpy.ndarray of Axes) – One axes per panel, top to bottom. Always an array, including for a single panel, so that indexing does not depend on the panel count.
Examples
import matplotlib matplotlib.use('Agg') import numpy as np from magnus.plotting import plot_curves_stacked E = np.linspace(1.0, 40.0, 200) cases = [0.5, 1.0, 2.0] panels = [ [dict(y=np.sin(k*E/8.0)**2, color=f'C{i}'), dict(y=np.sin(k*E/8.0)**2*0.8, color='0.7', ls='--')] for i, k in enumerate(cases) ] fig, ax = plot_curves_stacked( E, panels, xlabel=r'Neutrino energy, $E_\nu$ [GeV]', ylabel='Probability', ylim=(0, 1), xlim=(1.0, 40.0), panel_labels=[f'baseline {k:.1f} kton-yr' for k in cases], legend_proxies=[dict(label='3+1', color='k', ls='-'), dict(label=r'standard', color='k', ls='--')], ) print(ax.shape, ax[0].get_xticklabels()[0].get_text() == '')
(3,) True
- magnus.plotting.plot_probability_vs_baseline(distances: Sequence[float], curves: Sequence[Sequence[float] | Dict[str, Any]], *, nu_i: int | None = None, nu_f: int | None = None, num_flavors: int | None = None, xlabel: str = 'Baseline, $L$ [km]', ylabel: str | None = None, ylim: Tuple[float, float] = (0.0, 1.0), xscale: str = 'log', ymajor: float | None = 0.1, yminor: float | None = 0.02, **_forbidden: Any)[source]
Plot oscillation probabilities against baseline.
A thin preset over
plot_curves(): log abscissa, ordinate on \([0, 1]\) with the notebooks’ tick spacings, and an ordinate label built from the flavour pair.Added in version 1.0.0.
- Parameters:
distances (sequence of float) – Baselines [km].
curves (sequence) – As in
plot_curves().nu_i (int, optional) – Flavour pair, used to build the ordinate label via
prob_label()whenylabelis not given.nu_f (int, optional) – Flavour pair, used to build the ordinate label via
prob_label()whenylabelis not given.num_flavors (int, optional) – If given, prefixes the ordinate label with
'Two-','Three-','Four-'or'Five-neutrino probability'.xlabel (str, optional) – Abscissa label.
ylabel (str, optional) – Ordinate label; overrides the one built from the flavour pair.
ylim (tuple of float, optional) – Ordinate limits. Default is
(0.0, 1.0).xscale (str, optional) – Abscissa scale. Default is
'log'.ymajor (float, optional) – Ordinate tick spacings.
yminor (float, optional) – Ordinate tick spacings.
**_forbidden – Every remaining keyword of
plot_curves()is accepted and forwarded unchanged; unknown names raiseTypeErrorthere.
- Returns:
fig (matplotlib.figure.Figure)
ax (matplotlib.axes.Axes or numpy.ndarray of Axes)
Examples
import matplotlib matplotlib.use('Agg') import numpy as np import magnus.globaldefs as gd from magnus.plotting import plot_probability_vs_baseline L = np.logspace(1, 5, 200) P = np.sin(L / 3000.0) ** 2 fig, ax = plot_probability_vs_baseline( L, [dict(y=P, label='Magnus expansion')], nu_i=gd.NUE, nu_f=gd.NUE, num_flavors=2, xlim=(L[0], L[-1]), ) print(ax.get_xlabel())
Baseline, $L$ [km]
- magnus.plotting.plot_probability_vs_energy(energies: Sequence[float], curves: Sequence[Sequence[float] | Dict[str, Any]], *, nu_i: int | None = None, nu_f: int | None = None, num_flavors: int | None = None, energy_unit: str = 'GeV', xlabel: str | None = None, ylabel: str | None = None, ylim: Tuple[float, float] = (0.0, 1.0), xscale: str = 'log', ymajor: float | None = 0.1, yminor: float | None = 0.02, **_forbidden: Any)[source]
Plot oscillation probabilities against neutrino energy.
The energy counterpart of
plot_probability_vs_baseline().Added in version 1.0.0.
- Parameters:
energies (sequence of float) – Neutrino energies, in the unit named by
energy_unit.curves (sequence) – As in
plot_curves().nu_i (int, optional) – Flavour pair for the ordinate label.
nu_f (int, optional) – Flavour pair for the ordinate label.
num_flavors (int, optional) – Flavour count, for the ordinate label prefix.
energy_unit (str, optional) – Unit shown in the abscissa label. Default is
'GeV'.xlabel (str, optional) – Abscissa label; overrides the one built from
energy_unit.ylabel (str, optional) – Ordinate label.
ylim (tuple of float, optional) – Ordinate limits. Default is
(0.0, 1.0).xscale (str, optional) – Abscissa scale. Default is
'log'.ymajor (float, optional) – Ordinate tick spacings.
yminor (float, optional) – Ordinate tick spacings.
**_forbidden – Forwarded to
plot_curves().
- Returns:
fig (matplotlib.figure.Figure)
ax (matplotlib.axes.Axes or numpy.ndarray of Axes)
Examples
import matplotlib matplotlib.use('Agg') import numpy as np import magnus.globaldefs as gd from magnus.plotting import plot_probability_vs_energy E = np.logspace(-1, 1, 200) P = np.cos(1.0 / E) ** 2 fig, ax = plot_probability_vs_energy( E, [dict(y=P, label='Magnus expansion')], nu_i=gd.NUMU, nu_f=gd.NUE, xlim=(E[0], E[-1]), ) print(ax.get_xlabel())
Neutrino energy, $E_\nu$ [GeV]
- magnus.plotting.plot_probability_with_profile(x: Sequence[float], profiles: Sequence[Sequence[float] | Dict[str, Any]] | None, panels: Sequence[Sequence[Sequence[float] | Dict[str, Any]]], *, xlabel: str = 'Baseline, $L$~[km]', profile_ylabel: str = '$\\frac{N_e}{N_{\\rm Av}}$~[cm$^{-3}$]', panel_ylabels: Sequence[str | None] | None = None, panel_annotations: Sequence[str | None] | None = None, panel_annotation_xy: Tuple[float, float] = (0.02, 0.88), panel_annotation_fontsize: float = 23.0, shared_ylabel: str | None = None, shared_ylabel_labelpad: float = 20.0, title: str | None = None, title_fontsize: float = 23.0, xlim: Tuple[float, float] | None = None, xscale: str = 'log', xmajor: float | None = None, xminor: float | None = None, profile_ylim: Tuple[float, float] | None = None, profile_ymajor: float | None = None, profile_yminor: float | None = None, profile_height: float = 0.4, panel_ylim: Tuple[float, float] | None = (0.0, 1.0), panel_yscale: str = 'linear', panel_ymajor: float | None = 0.1, panel_yminor: float | None = 0.02, legend: bool = True, legend_title: str | None = None, legend_loc: str | None = None, legend_kw: Dict[str, Any] | None = None, legend_on_panel: int = 0, grid: bool = True, grid_kw: Dict[str, Any] | None = None, ylabel_labelpad: float = 25.0, figsize: Tuple[float, float] | None = None, subplots_kw: Dict[str, Any] | None = None, savefig: str | None = None, savefig_kw: Dict[str, Any] | None = None, tight_layout: bool = False)[source]
Stack a matter-density panel above one or more probability panels.
This is the layout of the long-baseline notebook: the electron-density profile along the trajectory on top, then one probability panel per detector or per profile, sharing the abscissa. With a single probability panel it is the profile-plus-probability figure of the introduction and the two-flavour notebooks.
Added in version 1.0.0.
- Parameters:
x (sequence of float) – Shared abscissa, or, when the panels have different abscissae, the one used by the profile panel. Individual curves may carry their own
x.profiles (sequence or None) – Curves for the density panel, in the form
plot_curves()takes. A curve may add its own abscissa under'x'. PassNone(or an empty sequence) to omit the density panel entirely and get a plain stack of probability panels sharing an abscissa – the layout the long-baseline notebook uses for a probability above its energy-smoothed version.panels (sequence of sequence) – One entry per probability panel; each entry is a sequence of curves.
xlabel (str, optional) – Abscissa label, placed under the bottom panel.
profile_ylabel (str, optional) – Ordinate label of the density panel.
panel_ylabels (sequence of str, optional) – Ordinate labels for the probability panels. Entries may be
None.panel_annotations (sequence, optional) – Text placed inside each probability panel, one entry per panel, at
panel_annotation_xyin axes coordinates. An entry is a string, or a dict with'text'plus any otherannotate()keyword – abbox, for instance, when the text would otherwise sit over dense curves. Entries may beNone. The three-flavour notebook uses this to name the channel each panel shows, rather than repeating it in the ordinate label.panel_annotation_xy (tuple of float, optional) – Position of those annotations, in axes fractions. Default
(0.02, 0.88).panel_annotation_fontsize (float, optional) – Their font size. Default is
23.0.shared_ylabel (str, optional) – A single ordinate label spanning the whole stack, drawn on a frameless overlay axes. Use it instead of
panel_ylabelswhen every panel shows the same quantity.shared_ylabel_labelpad (float, optional) – Padding of that shared label. Default is
20.0.title (str, optional) – Title, placed above the density panel.
title_fontsize (float, optional) – Title font size. Default is
23.0.xscale (str, optional) – Shared abscissa scale. Default is
'log'.xmajor (float, optional) – Major/minor tick spacings on the shared abscissa. Only meaningful on a linear scale.
xminor (float, optional) – Major/minor tick spacings on the shared abscissa. Only meaningful on a linear scale.
profile_ylim (tuple of float, optional) – Ordinate limits of the density panel.
profile_ymajor (float, optional) – Tick spacings for the density panel.
profile_yminor (float, optional) – Tick spacings for the density panel.
profile_height (float, optional) – Height of the density panel relative to a probability panel. Default is
0.4.panel_ylim (tuple of float, optional) – Ordinate limits shared by the probability panels.
Noneautoscales.panel_yscale (str, optional) – Ordinate scale shared by the panels, e.g.
'log'when they carry something other than a probability. Default is'linear'.panel_ymajor (float, optional) – Tick spacings for the probability panels.
panel_yminor (float, optional) – Tick spacings for the probability panels.
legend (bool, optional) – Whether to draw a legend.
legend_title (str, optional) – Legend title.
legend_loc (str, optional) – Legend location.
legend_kw (dict, optional) – Extra keywords merged over
HOUSE_LEGEND_KW.legend_on_panel (int, optional) – Index of the probability panel carrying the legend, or
-1to give every panel its own. Default is0.grid (bool, optional) – Whether to draw grids. Default is
True.grid_kw (dict, optional) – Extra keywords merged over
HOUSE_GRID_KW.ylabel_labelpad (float, optional) – Padding of the ordinate labels.
figsize (tuple of float, optional) – Figure size. Defaults to
(18, 9)for one probability panel, growing by 4.5 inches per extra panel.subplots_kw (dict, optional) – Extra keywords for
subplots().savefig (str, optional) – If given, the figure is written here.
savefig_kw (dict, optional) – Extra keywords merged over
HOUSE_SAVEFIG_KW.tight_layout (bool, optional) – Whether to call
tight_layout. Default isFalse, matching the notebooks, whose explicitsubplots_adjustthis would override.
- Returns:
fig (matplotlib.figure.Figure)
ax (numpy.ndarray of Axes) – Length
1 + len(panels)with a density panel, which comes first; lengthlen(panels)without one.
Examples
import matplotlib matplotlib.use('Agg') import numpy as np from magnus.plotting import plot_probability_with_profile L = np.logspace(2, 4, 300) n_e = 5.0 * np.exp(-L / 5000.0) P = np.sin(L / 900.0) ** 2 fig, ax = plot_probability_with_profile( L, [dict(y=n_e, color='C0')], [[dict(y=P, label='PREM')]], xlim=(L[0], L[-1]), profile_ylim=(0, 6), ) print(len(ax))
2
- magnus.plotting.plot_probability_with_average(x: Sequence[float], probabilities: Sequence[float] | Sequence[Sequence[float]], averages: float | Sequence[float] | Sequence[Sequence[float]], *, labels: Sequence[str] | None = None, colors: Sequence[str] | None = None, average_label: str = 'Phase-averaged', oscillating_kw: Dict[str, Any] | None = None, average_kw: Dict[str, Any] | None = None, **_forbidden: Any)[source]
Overlay phase-averaged probabilities on the oscillating ones.
The figure of the averaged-probability notebook: rapidly oscillating curves, each with its decohered limit drawn through it as a dashed line of the same colour – the value
magnus.oscprob.osc_prob()returns withaverage=True.Several channels are usually shown at once, so the legend carries one entry per channel plus a single entry explaining the dashed style, rather than repeating “averaged” once per curve.
Added in version 1.0.0.
- Parameters:
x (sequence of float) – Abscissa, typically baseline [km].
probabilities (sequence of float or sequence of sequence of float) – One oscillating probability, or several.
averages (float or sequence) – The corresponding phase-averaged values: a scalar per curve (broadcast across
x), or a full curve each. Must matchprobabilitiesin number.labels (sequence of str, optional) – Legend label per channel.
colors (sequence of str, optional) – Colour per channel. Defaults to the
'C0','C1', … cycle; each average takes its channel’s colour.average_label (str, optional) – Text of the single legend entry explaining the dashed lines.
oscillating_kw (dict, optional) – Extra
Line2Dkeywords applied to every oscillating or every averaged curve.average_kw (dict, optional) – Extra
Line2Dkeywords applied to every oscillating or every averaged curve.**_forbidden – Forwarded to
plot_probability_vs_baseline().
- Returns:
fig (matplotlib.figure.Figure)
ax (matplotlib.axes.Axes or numpy.ndarray of Axes)
- Raises:
ValueError – If the number of averages does not match the number of probabilities.
Examples
import matplotlib matplotlib.use('Agg') import numpy as np from magnus.plotting import plot_probability_with_average L = np.linspace(1.0, 1000.0, 500) P = np.sin(L / 7.0) ** 2 fig, ax = plot_probability_with_average(L, P, 0.5, xscale='linear') print(len(ax.get_lines()))
2
- magnus.plotting.plot_biprobability(prob_nu: Sequence[Sequence[float]], prob_nubar: Sequence[Sequence[float]], *, labels: Sequence[str] | None = None, curve_kw: Sequence[Dict[str, Any]] | None = None, markers: Sequence[Dict[str, Any]] | None = None, xlabel: str | None = None, ylabel: str | None = None, title: str | None = None, title_fontsize: float = 20.0, xlim: Tuple[float, float] | None = None, ylim: Tuple[float, float] | None = None, xmajor: float | None = None, xminor: float | None = None, ymajor: float | None = None, yminor: float | None = None, annotations: Sequence[Dict[str, Any]] | None = None, legend: bool = True, legend_title: str = '$\\delta_{\\rm CP}$', legend_loc: str | None = None, legend_kw: Dict[str, Any] | None = None, figsize: Tuple[float, float] = (9.0, 9.0), subplots_kw: Dict[str, Any] | None = None, savefig: str | None = None, savefig_kw: Dict[str, Any] | None = None, tight_layout: bool = False)[source]
Plot neutrino against antineutrino appearance probability.
The bi-probability plane: for each configuration, the locus traced out as \(\delta_{\rm CP}\) runs over \([-\pi, \pi]\), with optional markers at selected phases.
Added in version 1.0.0.
- Parameters:
prob_nu (sequence of sequence of float) – One entry per curve, each a sequence of probabilities over the same grid of \(\delta_{\rm CP}\) values.
prob_nubar (sequence of sequence of float) – One entry per curve, each a sequence of probabilities over the same grid of \(\delta_{\rm CP}\) values.
labels (sequence of str, optional) – Legend label per curve.
curve_kw (sequence of dict, optional) – Per-curve
Line2Dkeywords.markers (sequence of dict, optional) – Markers at selected phases. Each entry gives its position either as
'index'(a position along the curve) or as'xy'(an explicit coordinate pair, which is what you have when the marked phases were computed separately from the curve). Optionally'marker','label','filled'and'curve'(which curve it belongs to, default all).xlabel (str, optional) – Axis labels. Default to the \(\nu_\mu \to \nu_e\) pair.
ylabel (str, optional) – Axis labels. Default to the \(\nu_\mu \to \nu_e\) pair.
title (str, optional) – Title.
title_fontsize (float, optional) – Title font size.
xmajor (float, optional) – Tick spacings.
xminor (float, optional) – Tick spacings.
ymajor (float, optional) – Tick spacings.
yminor (float, optional) – Tick spacings.
annotations (sequence of dict, optional) – Passed to
annotate(); each entry needs'text'and'xy', and may carry any other annotate keyword. Coordinates are axes fractions.legend (bool, optional) – Whether to draw a legend.
legend_title (str, optional) – Legend title. Default is
'$\\delta_{\\rm CP}$'.legend_loc (str, optional) – Legend location.
legend_kw (dict, optional) – Extra keywords merged over
HOUSE_LEGEND_KW.figsize (tuple of float, optional) – Figure size. Default is
(9.0, 9.0), the square panel this plot uses.subplots_kw (dict, optional) – Extra keywords for
subplots().savefig (str, optional) – If given, the figure is written here.
savefig_kw (dict, optional) – Extra keywords merged over
HOUSE_SAVEFIG_KW.tight_layout (bool, optional) – Whether to call
tight_layout. Default isFalse.
- Returns:
fig (matplotlib.figure.Figure)
ax (matplotlib.axes.Axes)
Examples
import matplotlib matplotlib.use('Agg') import numpy as np from magnus.plotting import plot_biprobability d = np.linspace(-np.pi, np.pi, 100) P_nu = 0.05 + 0.02 * np.sin(d) P_nubar = 0.04 + 0.02 * np.sin(d + 0.4) fig, ax = plot_biprobability([P_nu], [P_nubar], labels=['NO']) print(ax.get_xlabel())
$P_{\nu_\mu \to \nu_e}$
- magnus.plotting.plot_oscillogram(costhz: Sequence[float], log10_energy: Sequence[float], probability: Sequence[Sequence[float]], *, nu_i: int | None = None, nu_f: int | None = None, levels: int = 120, cmap: str = 'plasma', xlabel: str = 'Zenith angle, $\\cos(\\theta_z)$', ylabel: str = 'Neutrino energy, $\\log_{10}(E_\\nu/{\\rm GeV})$', cbar_label: str | None = None, cbar_label_prefix: str = '', cbar_fontsize: float = 25.0, cbar_labelsize: float = 25.0, annotation: str | None = None, annotation_fontsize: float = 23.0, xlim: Tuple[float, float] | None = None, ylim: Tuple[float, float] | None = None, xmajor: float | None = 0.2, xminor: float | None = 0.02, ymajor: float | None = 0.1, yminor: float | None = 0.02, figsize: Tuple[float, float] = (9.0, 9.0), contourf_kw: Dict[str, Any] | None = None, subplots_kw: Dict[str, Any] | None = None, savefig: str | None = None, savefig_kw: Dict[str, Any] | None = None, tight_layout: bool = False)[source]
Plot an oscillogram: probability over zenith angle and energy.
A filled contour map of the oscillation probability in the plane of \(\cos\theta_z\) (equivalently, baseline through the Earth) and \(\log_{10} E_\nu\), with a colour bar and the channel annotated in the corner over a white stroke so it stays legible against the colour map.
Added in version 1.0.0.
- Parameters:
costhz (sequence of float) – Zenith-angle cosines, the abscissa.
log10_energy (sequence of float) – \(\log_{10}\) of the energy in GeV, the ordinate.
probability (sequence of sequence of float) – Probability with shape
(len(log10_energy), len(costhz)).nu_i (int, optional) – Flavour pair, used for the colour-bar label and the annotation when those are not given explicitly.
nu_f (int, optional) – Flavour pair, used for the colour-bar label and the annotation when those are not given explicitly.
levels (int, optional) – Number of filled contour levels. Default is
120.cmap (str, optional) – Colour map. Default is
'plasma'.xlabel (str, optional) – Axis labels.
ylabel (str, optional) – Axis labels.
cbar_label (str, optional) – Colour-bar label; overrides the one built from the flavour pair.
cbar_label_prefix (str, optional) – Text placed before the probability label on the colour bar.
cbar_fontsize (float, optional) – Colour-bar label and tick-label sizes.
cbar_labelsize (float, optional) – Colour-bar label and tick-label sizes.
annotation (str, optional) – Corner annotation. Defaults to the probability label when the flavour pair is given; pass
''to suppress it.annotation_fontsize (float, optional) – Corner annotation size.
xlim (tuple of float, optional) – Axis limits. Default to the data range.
ylim (tuple of float, optional) – Axis limits. Default to the data range.
xmajor (float, optional) – Tick spacings.
xminor (float, optional) – Tick spacings.
ymajor (float, optional) – Tick spacings.
yminor (float, optional) – Tick spacings.
figsize (tuple of float, optional) – Figure size. Default is
(9.0, 9.0).contourf_kw (dict, optional) – Extra keywords for
contourf().subplots_kw (dict, optional) – Extra keywords for
subplots().savefig (str, optional) – If given, the figure is written here.
savefig_kw (dict, optional) – Extra keywords merged over
HOUSE_SAVEFIG_KW.tight_layout (bool, optional) – Whether to call
tight_layout. Default isFalse.
- Returns:
fig (matplotlib.figure.Figure)
ax (matplotlib.axes.Axes)
Examples
import matplotlib matplotlib.use('Agg') import numpy as np import magnus.globaldefs as gd from magnus.plotting import plot_oscillogram c = np.linspace(-1.0, 0.0, 40) lE = np.linspace(-1.0, 1.0, 30) P = np.sin(np.outer(10 ** lE, 1.0 + c)) ** 2 fig, ax = plot_oscillogram(c, lE, P, nu_i=gd.NUMU, nu_f=gd.NUMU) print(ax.get_xlabel())
Zenith angle, $\cos(\theta_z)$