Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Setting defaults once, with rcParams

I have typed cmap="viridis" into eleven calls in this notebook. Is there one place I can say it instead?

There is: mnutils.rcParams, a single validated mapping of every default MNUtils ships. It works the way matplotlib.rcParams does, deliberately — the muscle memory transfers, including the escape hatches.

ObjectWhat it does here
rcParamsthe live mapping every MNUtils function reads its defaults from
rc_context()applies overrides for one block, then puts them back
rcdefaults()restores the built-ins
rc_presetsnamed override bundles ("poster", "talk", "paper")
display_images()the grid whose panel size the last section retunes
MRISeriesthe anatomical series every example here displays
get_display_zooms()the physical (row, col) voxel spacing that keeps the render proportioned

What is in there

['grid.max_cols', 'grid.max_height', 'grid.panel_height', 'grid.panel_min_height', 'grid.panel_min_width', 'image.ax.xlabel', 'image.ax.xticks', 'image.ax.ylabel', 'image.ax.yticks', 'image.cmap', 'image.mask.colors', 'image.mask.linewidths', 'nifti.orientation', 'nifti.resample.cval', 'nifti.resample.mode', 'nifti.resample.order', 'save.bbox_inches', 'save.dpi', 'save.format', 'save.pad_inches', 'save.transparent', 'spectra.ticker_steps', 'spectra.xlabel', 'spectra.xlim', 'spectra.xticker_bins', 'spectra.ylabel', 'spectra.yticker_bins']

Every example below displays one anatomical volume, from a fake exam built on the fly by mnutils.testing.build_fake_exam -- the same fixtures the GESeries page uses:

((256, 188, 186), (0.8799999952316284, 0.8799999952316284))

The names are dotted and grouped by what they configure: image.* for how image panels are drawn, grid.* for how big the display_images grid gets, spectra.* for spectral axes, nifti.* for orientation and resampling, save.* for figure saving.

('magma', ('L', 'P', 'S'))

Change it for the session

Assign, and every later call picks it up:

Loading...

An anatomical scan wants "gray", of course -- which is what the next section is for.

Why this works at all — and why it didn’t before

A default that lives in a function signature is evaluated once, at import:

def display_images(..., cmap: str = DEFAULT_PARAMS["cmap"]):  # ❌ frozen

Assigning to DEFAULT_PARAMS after import mnutils then changes nothing — the signature already captured the old string. Every MNUtils entry point instead takes None and resolves it in the body, via resolve_rc():

def display_images(..., cmap: str | None = None):  # ✅ read at call time
    cmap = resolve_rc(cmap, "image.cmap")

That is the whole reason rcParams is a module of its own rather than a dict per module.

Change it for one block

A session-wide assignment is the wrong tool when one figure needs different treatment. rc_context() applies overrides and restores whatever was there before, exception or not:

inside : gray
outside: viridis

rcdefaults() puts everything back, which is the fastest way out of a notebook whose defaults have drifted:

'magma'

The saving contexts are the same mechanism wearing a name. save_figure(..., context="poster") applies the "poster" entry of rc_presets through rc_context — there is no separate poster-parameters dict to keep in sync:

{'poster': {'save.dpi': 300}, 'talk': {'save.transparent': True}, 'paper': {'save.dpi': 300, 'save.pad_inches': 0.1}}

A typo raises instead of doing nothing

Every assignment goes through a validator that owns that key, so the failure lands where the mistake is:

"'image.cmpa' is not a valid rcParam; did you mean 'image.cmap'?"
invalid value for rcParams['nifti.orientation']: expected three axis codes from AILPRS, got ('L', 'P', 'Z')

Bigger panels for an anatomical series

The default grid is tuned for a row of low-resolution multi-nuclear panels. A high-resolution anatomical slice at that size throws away most of what is in the data — so grid.panel_height exists, and so does a per-call argument for the one figure that needs it:

Loading...
Loading...

Pass grid_max_height alongside it when the taller panels start scrolling inside their box, and set mnutils.rcParams["grid.panel_height"] instead when every grid in the notebook should be bigger.

Precedence runs in the order you would guess, and it is the same for every parameter in this page: