This is a pure Python module for taking slices through MR Images and displaying them in beautiful ways. It is friendly to both clinical and pre-clinical data, and includes dual-coding (http://dx.doi.org/10.1016/j.neuron.2012.05.001) overlays.

This is an example of an image you can make with it:

_images/dualcode.png

And here is an example of the viewer application:

_images/viewer.png

Along with the nanslice module that can be used in your Python scripts, there are several utitlity functions for use in jupyter notebooks, including a three-plane viewer. There are also three command line tools that will installed to your $PATH:

  • nanslicer Produces different kind of slice-plots including color bars
  • nanviewer A three-plane viewer. Requires PyQt.
  • nanvideo Converts time-series images to a movie file for easy viewing.

Why does nanslice exist when there are plenty of other great MR viewing tools, e.g. [FSLEyes](https://fsl.fmrib.ox.ac.uk/fsl/fslwiki/FSLeyes) or [MRIcroGL](http://www.cabiatl.com/mricrogl/)? There are three reasons:

  • Compatibility with pre-clinical data. Small animals (rodents) are scanned in a different orientation to humans, and hence have different definitions of superior-inferior and posterior-anterior. This makes using such images with clinically focussed tools tedious.
  • Support for [dual-coding overlays](https://www.cell.com/neuron/fulltext/S0896-6273(12)00428-X)
  • [Inner-Platform Effect](https://en.wikipedia.org/wiki/Inner-platform_effect). Seen as you have to learn scripting languages if you want to have repeatable plots in other tools, you might as well build your plots with a common language straight away.

(Note: I love both MRIcroGL and FSLEyes, I use them all the time)

Okay, there’s a fourth reason. I am fussy about plots. I spend a lot of time on then. Having immediate access to all of matplotlib is a brilliant way to make beautiful plots (and also to waste hours obessessing about your choice of fonts. Avenir Next is a hell of a drug).

nanslice

nanslice package

The nanslice package. Everything important is in a submodule, but the Slicer and Layer classes, and the blend_layers() function, are imported here for convenient access. Between them, they do all the important work.

Submodules

nanslice.slicer module

slicer.py

This module contains the core Slicer object that samples Layers to produce image arrays that can be drawn with matlplotlib.

class nanslice.slicer.Slicer(bbox, pos, axis, samples=64, orient='clin')[source]

Bases: object

The Slicer class.

When constructed, creates an array of world-space co-ordinates which represent the desired slice

Constructor Parameters:

  • bbox – Box instance that defines the world-space bounding box that you want to slice
  • pos – Position within the box to generate the slice through
  • axis – Which axis you want to slice across. Either x/y/z or 0/1/2
  • samples – Number of samples in the horizontal direction
  • orient – ‘clin’ or ‘preclin’
get_voxel_coords(tfm)[source]

Returns an array of voxel space co-ordinates for this slice, which will be cached. If a subsequent call uses the same affine transform, the cached co-ordinates will be returned. If a new transform is passed in, then a fresh set of co-ordinates are calculated first.

Parameters:

  • tfm – An affine transform that defines an images physical space (usually the .affine property of an nibabel image)
sample(img, order, scale=1.0, volume=0)[source]

Samples the passed 3D/4D image and returns a 2D slice

Paramters:

  • img – An nibabel image
  • order – Interpolation order. 1 is linear interpolation
  • scale – Scale factor to multiply all voxel values by
  • volume – If sampling 4D data, specify the desired volume
nanslice.slicer.axis_indices(axis, orient='clin')[source]

Returns a pair of indices corresponding to right/up for the given orientation. Parameters: axis: The perpendicular axis to the slice. Use Axis_map to convert between x/y/z and 0/1/2 orient: Either ‘clin’ or ‘preclin’

nanslice.layer module

layer.py

Contains the Layer class and the blend_layers() function.

class nanslice.layer.Layer(image, scale=1.0, volume=0, interp_order=1, cmap=None, clim=None, label='', mask=None, mask_threshold=0, alpha=None, alpha_lim=None, alpha_scale=1.0, alpha_label='')[source]

Bases: object

The Layer class

Each layer consists of a base MR image, with optional mask and alpha (transparency) images and their associated parameters (colormap, limits, scales etc.)

Constructor parameters:

  • image – The image contained in this layer. Can be either a string/path to an image file or an nibabel image
  • scale – A scaling factor to multiply all voxels in the image by
  • volume – If reading a 4D file, specify which volume to use
  • interp_order – Interpolation order. 1 is linear interpolation
  • cmap – The colormap to apply to the Layer. Any valid matplotlib colormap
  • clim – The limits (min, max) values to use for the colormap
  • label – The label for this layer (used for colorbars)
  • mask – A mask image to use with this layer
  • mask_threshold – Apply a threshold (lower) to the mask
  • alpha – An alpha (transparency) image to use with this layer
  • alpha_lim – Specify the limits/window for the alpha image
  • alpha_scale – Scaling factor for the alpha image
  • alpha_label – Label for the alpha axis on alphabars
get_alpha(slicer)[source]

Returns the alpha (transparency) slice for this Layer

Parameters:

  • slicer – The Slicer object to slice this layer with
get_color(slicer)[source]

Returns a colorized slice through the base image contained in the Layer

Parameters:

  • slicer – The Slicer object to slice this layer with
get_mask(slicer)[source]
get_slice(slicer)[source]

Returns a slice through the base image

Parameters:

  • slicer – The Slicer object to slice this layer with
plot(slicer, axes)[source]

Plot a Layer into a Matplotlib axes using the provided Slicer

Parameters:

  • slicer – The Slicer object to slice this layer with
  • axes – A matplotlib axes object
nanslice.layer.blend_layers(layers, slicer)[source]

Blends together a set of overlays using their alpha information

Parameters:

  • layers – An iterable (e.g. list/tuple) of Layer objects
  • slicer – The Slicer object to slice the layers with

nanslice.box module

Box.py

Contains a simple bounding-box class

class nanslice.box.Box(center=None, size=None, corners=None)[source]

Bases: object

A simple bounding-box class

Constructor parameters:

  • center – The center of the box (x,y,z) in world-space co-ordinates
  • size – The size of the box (x,y,z) in world-space units
  • corners – Two corners (x,y,z) of the box in world-space co-ordinates

Either corners or both center and size must be specified

center

Returns the geometric center of the bounding-box

diag

Returns the vector diagonal of the bounding-box

end

Returns the ‘end’ corner of the bounding-box (opposite the start)

classmethod fromImage(img)[source]

Creates a bounding box from the corners defined by an image

Parameters:

  • img – An nibabel image
classmethod fromMask(img, padding=0)[source]

Creates a bounding box that encloses all non-zero voxels in a volume

Parameters:

  • img – The volume to create the bounding-box from
  • padding – Number of extra voxels to pad the resulting box by
slice_positions(num_slices, start=0, end=1)[source]

Returns an array of slice positions along the specified axis

start

Returns the ‘start’ corner of the bounding-box

nanslice.slice_func module

slice_func.py

Functions for manipulating ‘slices’/images (or (X, Y, 3) arrays)

nanslice.slice_func.blend(img_under, img_over, img_alpha)[source]

Blend together two images using an alpha channel image

Parameters:

  • img_under – The base image (underneath the overlay)
  • img_over – The overlay image
  • img_alpha – Transparency/alpha value to use when blending
nanslice.slice_func.blur(img, sigma=1)[source]

Blur an image with a Gaussian kernel

Parameters:

  • img – The image to blur
  • sigma – The FWHM of the Gaussian kernel, in voxels
nanslice.slice_func.checkerboard(img1, img2, square_size=16)[source]

Combine two images in a checkerboard pattern, useful for checking image registration quality. Idea stolen from @ramaana_ on Twitter

nanslice.slice_func.colorize(data, cmap, clims=None)[source]

Apply a colormap to grayscale data. Takes an (X, Y) array and returns an (X, Y, 3) array

Parameters:

  • data – The 2D scalar (X, Y) array to colorize
  • cmap – Any valid matplotlib colormap or colormap name
  • clims – The limits for the colormap
nanslice.slice_func.mask(img, img_mask, back=array([0, 0, 0]))[source]

Mask out sections of one image using another

Parameters:

  • img – The image to be masked
  • img_mask – The mask image
  • back – Background value
nanslice.slice_func.scale_clip(data, lims)[source]

Scale an image to fill the range 0-1 and clip values that fall outside that range

Parameters:

  • data – The image data array
  • lims – The limits to scale betwee

nanslice.jupyter module

nanslice.colorbar module

colorbar.py

Functions to create a colorbar and a dual-axis color/alphabar.

Matplotlib has no concept of an “alphabar”. In addition, because the standard matplotlib colormaps and colorbars only work on scalar (single-channel) input images, and matplotlib does not deal with alpha/transparency correctly, nanslice images are true-color RGB arrays. Hence we need to roll our own colorbar as well

nanslice.colorbar.alphabar(axes, cm_name, clims, clabel, alims, alabel, alines=None, alines_colors=('k', ), alines_styles=('solid', ), cfmt='{:.3g}', afmt='{:.2g}', black_backg=True, orient='h')[source]

Plots a 2D ‘alphabar’ with color and transparency axes in the specified matplotlib axes object

Parameters:

  • axes – matplotlib axes instance to use for plotting
  • cm_name – Colormap name
  • clims – The limits for the colormap & bar
  • clabel – Label to place on the color axis
  • alims – The limits for the transparency axis
  • alabel – Label to place on the transparency axis
  • alines – Add lines to indicate transparency values (e.g. p < 0.05). Can be a single number or an iterable
  • alines_colors – Colors to use for each alpha line. Length must match alines parameter
  • alines_styles – Line styles to use for each alpha line. Length must match alines parameter
  • cprecision – Precision of color axis ticks
  • aprecision – Precision of alpha axis ticks
  • black_bg – Boolean indicating if the background to this plot is black, and hence white text/borders should be used
  • orient – ‘v’ or ‘h’ for whether you want a vertical or horizontal colorbar
nanslice.colorbar.colorbar(axes, cm_name, clims, clabel, black_backg=True, show_ticks=True, tick_fmt='{:.2g}', orient='h')[source]

Plots a colorbar in the specified axes

Parameters:

  • axes – matplotlib axes instance to use for plotting
  • cm_name – Colormap name
  • clims – The limits for the colormap & bar
  • clabel – Label to place on the color axis
  • black_bg – Boolean indicating if the background to this plot is black, and hence white text/borders should be used
  • show_ticks – Set to false if you don’t want ticks on the color axis
  • tick_fmt – Valid format string for the tick labels
  • orient – ‘v’ or ‘h’ for whether you want a vertical or horizontal colorbar

nanslice.util module

util.py

Utility functions for nanslice module

nanslice.util.add_common_arguments(parser)[source]

Defines a set of common arguments that are shared between nanviewer and nanslicer

nanslice.util.center_of_mass(img)[source]

Calculates the center of mass of the image

nanslice.util.check_path(maybe_path)[source]

Helper function to check if an object is path-like

nanslice.util.ensure_image(maybe_path)[source]

Helper function that lets either images or paths be passed around

nanslice.nanslicer module

nanslicer.py

A command-line tool for producing figures with slices through MR images. This is installed by PIP as nanslicer. Supports overlays, dual-coded overlays and colorbars. Dual-coding is described here https://www.cell.com/neuron/fulltext/S0896-6273(12)00428-X.

The minimum command-line call is:

nanslicer image.nii.gz output.png

To add a dual-coded overlay, call:

nanslicer structural.nii.gz output.png --overlay beta.nii.gz --overlay_alpha pval.nii.gz

There are a lot of command-line options to control the colormaps and scaling. Type nanviewer --help to see a full list. The number of slices can be controlled with the --slice_rows and --slice_cols arguments, or you can choose --three_axis. The --slice_axis and --slice_lims arguments specify the axis along which to slice, and where to start and stop along it (expressed as fractions), for example:

nanslicer structural.nii.gz --slice_axis x --slice_lims 0.25 0.75

If you have timeseries data as the base image, you can plot the same slice through each volume with --timeseries, or you can choose the volume in the timeseries to use with --volume N (the default is the first).

Controlling image quality is slightly complicated because there are two interpolation steps. First we have to sample the 3D volumes to produce 2D slices to arbitrary precision. Then, matplotlib has to sample those slices to plot them to the canvas. The first step is controlled by --samples N, which controls the number of points to sample in each direction of the slice, and --interp_order N, which controls the quality of the interpolation. The defaults are 128 and 1 (linear interpolation). Increase them to increase the quality. The matplotlib step is controlled by --interp METHOD, and can be any valid matplotlib` interpolation method. The default is ``hanning, for increased speed this can be changed to linear or none. From experience, it is the quality of the matplotlib step which is the dominant factor in figure quality, hence the defaults of fairly fast sampling in the slicing step but using Hanning sampling in the matplotlib step.

nanslice.nanslicer.main(args=None)[source]

The main function that is called from the command line.

Parameters:

  • args – The command-line arguments. See module docstring or command-line help for a full list

nanslice.nanviewer module

nanslice.nanscroll module

nanscroll.py

This implements a command-line utility (installed as nanscroll) which will create a video scrolling through one axis of an image. This is installed by PIP as nanscroll.

The majority of options are the same as nanslicer.

nanslice.nanscroll.main(args=None)[source]

The main function for the utility.

Parameters:

  • args – The command line-arguments

Indices and tables