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:

And here is an example of the viewer application:

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 barsnanviewer
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
- bbox –
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
- slicer – The
-
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
- slicer – The
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.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.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.nanviewer module¶
Indices and tables¶
Legal¶
Copyright 2018 tobias.wood@kcl.ac.uk
This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this file, You can obtain one at http://mozilla.org/MPL/2.0/.