def _get_cuts(data, xcuts, ycuts, zcuts, n_cuts=5, interesting_cuts=False): """Returns xcuts, ycuts, & zcuts. If any of these are provided, they are used. If any are not provided, they are computed. The default is to compute unprovided cuts as evenly spaced slices across that dimension. However, if interesting_cuts is True, then any dimension's cuts that are not specified are computed using niplot.find_cut_slices.""" if interesting_cuts is True: # TODO: update Image_to_Nifti2Image to allow for multiple input types, and find a way to give it image metadata. raise NotImplementedError( "This functionality has not been fully implemented yet.") xcuts = xcuts or niplot.find_cut_slices(Image_to_Nifti2Image( atlas_Image, affine=np.eye(4)), direction='x', n_cuts=n_cuts).astype(int) ycuts = ycuts or niplot.find_cut_slices(Image_to_Nifti2Image( atlas_Image, affine=np.eye(4)), direction='y', n_cuts=n_cuts).astype(int) zcuts = zcuts or niplot.find_cut_slices(Image_to_Nifti2Image( atlas_Image, affine=np.eye(4)), direction='z', n_cuts=n_cuts).astype(int) else: xcuts = xcuts or np.linspace(0, data.shape[0], n_cuts + 2)[1:-1] ycuts = ycuts or np.linspace(0, data.shape[1], n_cuts + 2)[1:-1] zcuts = zcuts or np.linspace(0, data.shape[2], n_cuts + 2)[1:-1] return xcuts, ycuts, zcuts
def plot(self, downsample=1, out_base="."): out_path = os.path.join(out_base, self.subject, self.name, self.task) os.makedirs(out_path, exist_ok=True) raw = nib.load(self.path) M = np.max(raw.get_data()) n = raw.shape[3] mean = nimage.mean_img(raw) xyzcuts = nilplot.find_xyz_cut_coords(mean) xcuts = nilplot.find_cut_slices(mean, "x") ycuts = nilplot.find_cut_slices(mean, "y") zcuts = nilplot.find_cut_slices(mean, "z") del raw nrange = range(0, n, downsample) for i, img in enumerate(nimage.iter_img(self.path)): if i in nrange: nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/orth_epi%0d.png" % (out_path, i), annotate=True, cut_coords=xyzcuts, cmap="gist_heat") nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/x_epi%0d.png" % (out_path, i), annotate=True, display_mode="x", cut_coords=xcuts, cmap="gist_heat") nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/y_epi%0d.png" % (out_path, i), annotate=True, display_mode="y", cut_coords=ycuts, cmap="gist_heat") nilplot.plot_epi(nimage.math_img("img / %f" % (M), img=img), colorbar=False, output_file="%s/z_epi%0d.png" % (out_path, i), annotate=True, display_mode="z", cut_coords=zcuts, cmap="gist_heat") slice_names = ["orth_epi", "x_epi", "y_epi", "z_epi"] for slic in slice_names: filenames = ["%s/%s%0d.png" % (out_path, slic, i) for i in nrange] with imageio.get_writer('%s/%s.gif' % (out_path, slic), mode='I') as writer: for i, filename in zip(nrange, filenames): image = Image.open(filename) draw = ImageDraw.Draw(image) fnt = ImageFont.truetype('Pillow/Tests/fonts/FreeMono.ttf', 16) draw.text((2, 2), str(i), font=fnt, fill=(255, 0, 0, 255)) image.save(filename, "PNG") image = imageio.imread(filename) writer.append_data(image)
def pwi_save_png(perfusion_filename): """ Save perfusion weighted image to PNG for final report""" import os from nilearn import plotting, image import matplotlib.pyplot as plt xyz_direction = 'z' ncuts = 30 col = 6 row = 5 perfusion_dirname = os.path.dirname(perfusion_filename) cuts = plotting.find_cut_slices(image.load_img(perfusion_filename), direction=xyz_direction, n_cuts=ncuts, spacing='auto') print() print(cuts) print() cuts = [cuts[col * i:col * (i + 1)] for i in range(row)] print() print(cuts) print() output_file = [] for ii, jj in enumerate(cuts): output_file += [ os.path.abspath( os.path.join(perfusion_dirname, '_{0}_perfusion.png'.format(ii))) ] # print(output_file) plotting.plot_anat(perfusion_filename, cmap=plt.cm.hot, black_bg=True, display_mode=xyz_direction, cut_coords=jj, output_file=output_file[ii]) # http://stackoverflow.com/questions/30227466/combine-several-images-horizontally-with-python # montage_output_file = os.path.abspath(os.path.join(perfusion_dirname, 'perfusion.png' )) montage_output_file = output_file[2] return montage_output_file
def _process_fmri(self, fmri): if self.processing_mode.startswith("cut-slice-"): data = [ find_cut_slices(index_img(fmri, i), n_cuts=1)[0] for i in range(fmri.shape[-1]) ] return data if self.processing_mode == "act-series": series = build_series(fmri) return series.reshape(-1) else: raise ValueError(f"Invalid convert_mode {self.processing_mode}")
def plot_static_defaced(bids_dir, subject_id): defaced_img = nb.load( glob(os.path.join(bids_dir, 'sub-%s' % subject_id, 'anat/*T1w.nii.gz'))[0]) f, (ax1, ax2, ax3) = plt.subplots(3) plot_anat(defaced_img, draw_cross=False, annotate=False, display_mode='x', cut_coords=8, ax=ax1) plot_anat(defaced_img, draw_cross=False, annotate=False, display_mode='y', cut_coords=8, ax=ax2) plot_anat(defaced_img, draw_cross=False, annotate=False, display_mode='z', cut_coords=8) plt.show() fig = figure(figsize=(12, 7)) plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=-0.2, hspace=0) for i, e in enumerate(['x', 'y', 'z']): ax = fig.add_subplot(3, 1, i + 1) cuts = find_cut_slices(defaced_img, direction=e, n_cuts=12)[2:-2] plot_anat(defaced_img, display_mode=e, cut_coords=cuts, annotate=False, axes=ax, dim=-1) plt.show()
def plot_overlay_xyz(background, overlay, xyz_direction, cut_coords, out_dir=os.getcwd(), cmap='redblue', **kwargs): """ Creates a nCut png images from the NIFTI image """ # Create output directory if it doesn't exist if not os.path.exists(out_dir): os.makedirs(out_dir) # Loop over cuts and create background image # if len(cut_coords) == 1: cuts = plotting.find_cut_slices(image.load_img(background), direction=xyz_direction, n_cuts=cut_coords, spacing='auto') # else: # cuts = cut_coords for ii, jj in enumerate(cuts): output_file = os.path.abspath( os.path.join( out_dir, 'overlay_{0}_{1:03}'.format(xyz_direction, ii) + '.png')) plotting.plot_stat_map(overlay, bg_img=background, cmap=redblue_bipolar(), display_mode=xyz_direction, cut_coords=[jj], output_file=output_file, **kwargs)
def plot_multi_slices(img, cut_dir="z", n_cuts=20, n_cols=4, figsize=(2.5, 3), title="", title_fontsize=32, plot_func=None, black_bg=True, **kwargs): """ Create a plot of `n_cuts` of `img` organized distributed in `n_cols`. Parameters ---------- img: niimg-like cut_dir: str, optional Sectional direction; possible values are "x", "y" or "z". n_cuts: int, optional Number of cuts in the plot. n_cols: int, optional Maximum number of image columns in the plot. figsize: 2-tuple of int, optional (w, h) size in inches of the figure. title: str, optional The superior title of the figure. title_fontsize: int, optional The size of the title font. plot_func: function, optional Function to plot each slice. Default: nilearn.plotting.plot_stat_map black_bg: boolean, optional If True, the background of the image is set to be black. If you wish to save figures with a black background, you will need to pass "facecolor='k', edgecolor='k'" to matplotlib.pyplot.savefig. kwargs: keyword arguments, optional Input arguments for plot_func. Returns ------- fig: matplotlib.figure """ import math import matplotlib.pyplot as plt from matplotlib import gridspec import nilearn.plotting as niplot import nilearn.image as niimg # there is another version without grouper, but it is less efficient. def grouper(iterable, n, fillvalue=None): "Collect data into fixed-length chunks or blocks" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx import itertools args = [iter(iterable)] * n return itertools.zip_longest(fillvalue=fillvalue, *args) if plot_func is None: plot_func = niplot.plot_stat_map _img = niimg.load_img(img) n_rows = 1 if n_cuts > n_cols: n_rows = math.ceil(n_cuts / n_cols) spacing = kwargs.get('spacing', 'auto') cuts = niplot.find_cut_slices(_img, n_cuts=n_cuts, direction=cut_dir, spacing=spacing) # instantiate the figure if black_bg: facecolor = 'black' titlecolor = 'white' else: facecolor = 'white' titlecolor = 'black' figsize = figsize[0] * n_cols, figsize[1] * n_rows fig = plt.figure(figsize=figsize, facecolor=facecolor) gs = gridspec.GridSpec(n_rows, 1) if title: fig.suptitle(title, fontsize=title_fontsize, color=titlecolor) # for the superior plot put_colorbar = True # make the plots for i, cut_chunks in enumerate(grouper(cuts, n_cols)): ax = plt.subplot(gs[i]) cut_chunks = [cut for cut in cut_chunks if cut is not None] try: p = plot_func(_img, display_mode=cut_dir, cut_coords=cut_chunks, colorbar=put_colorbar, figure=fig, axes=ax, black_bg=black_bg, **kwargs) except IndexError: logging.warning('Could not plot for coords {}.'.format(cut_chunks)) finally: put_colorbar = False return fig
def plot_ortho_slices(img, n_cuts=4, n_cols=6, figsize=(2.5, 3), title="", title_fontsize=32, plot_func=None, black_bg=True, **kwargs): """ Parameters ---------- img: niimg-like n_cuts: int, optional Number of cuts for each dimension (X, Y, and Z) in the plot. n_cols: int, optional Maximum number of image columns in the plot. figsize: 2-tuple of int, optional (w, h) size in inches of one slice image. title: str, optional The superior title of the figure. title_fontsize: int, optional The size of the title font. plot_func: function, optional Function to plot each slice. Default: nilearn.plotting.plot_stat_map black_bg: boolean, optional If True, the background of the image is set to be black. If you wish to save figures with a black background, you will need to pass "facecolor='k', edgecolor='k'" to matplotlib.pyplot.savefig. kwargs: keyword arguments, optional Input arguments for plot_func. Returns ------- fig: matplotlib.figure """ from matplotlib import pyplot as plt from matplotlib import gridspec import nilearn.plotting as niplot import nilearn.image as niimg if plot_func is None: plot_func = niplot.plot_stat_map # load the image file _img = niimg.load_img(img) directions = ('x', 'y', 'z') # calculate the shape of the figure total_cuts = n_cuts * 3 if total_cuts > n_cols: n_rows = 3 n_cols = 1 colorbard_idx = 0 else: n_rows = 1 n_cols = 3 colorbard_idx = len(directions) - 1 # calculate the cut coordinates for each direction cuts = [] spacing = kwargs.get('spacing', 'auto') for cut_dir in directions: dir_cuts = niplot.find_cut_slices(_img, n_cuts=n_cuts, direction=cut_dir, spacing=spacing) cuts.append((cut_dir, dir_cuts)) # instantiate the figure if black_bg: facecolor = 'black' titlecolor = 'white' else: facecolor = 'white' titlecolor = 'black' figsize = figsize[0] * n_cols * n_cuts, figsize[1] * n_rows fig = plt.figure(figsize=figsize, facecolor=facecolor) gs = gridspec.GridSpec(n_rows, n_cols) # put the title, if any if title: fig.suptitle(title, fontsize=title_fontsize, color=titlecolor) # plot on the figure for i, (cut_dir, cut_coords) in enumerate(cuts): ax = plt.subplot(gs[i]) put_colorbar = True if i == colorbard_idx else False try: p = plot_func(_img, display_mode=cut_dir, cut_coords=cut_coords, colorbar=put_colorbar, figure=fig, axes=ax, black_bg=black_bg, **kwargs) except IndexError: logging.warning('Could not plot for coords {}.'.format(cut_coords)) return fig
def plot_multi_slices(img, cut_dir="z", n_cuts=20, n_cols=4, figsize=(2.5, 3), title="", title_fontsize=32, plot_func=None, **kwargs): """ Create a plot of `n_cuts` of `img` organized distributed in `n_cols`. Parameters ---------- img: niimg-like cut_dir: str Sectional direction; possible values are "x", "y" or "z". n_cuts: int Number of cuts in the plot. n_cols: int Maximum number of image columns in the plot. figsize: 2-tuple of int (w, h) size in inches of the figure. title: str The superior title of the figure. title_fontsize: int The size of the title font. plot_func: function Function to plot each slice. Default: nilearn.plotting.plot_stat_map kwargs: keyword arguments Input arguments for plot_func. Returns ------- fig: matplotlib.figure """ import math from matplotlib import pyplot as plt from matplotlib import gridspec import nilearn.plotting as niplot import nilearn.image as niimg # there is another version without grouper, but it is less efficient. def grouper(iterable, n, fillvalue=None): "Collect data into fixed-length chunks or blocks" # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx import itertools args = [iter(iterable)] * n return itertools.zip_longest(fillvalue=fillvalue, *args) if plot_func is None: plot_func = niplot.plot_stat_map _img = niimg.load_img(img) n_rows = 1 if n_cuts > n_cols: n_rows = math.ceil(n_cuts/n_cols) cuts = niplot.find_cut_slices(_img, n_cuts=n_cuts, direction=cut_dir) figsize = figsize[0] * n_cols, figsize[1] * n_rows fig = plt.figure(figsize=figsize, facecolor='black') gs = gridspec.GridSpec(n_rows, 1) if title: fig.suptitle(title, fontsize=title_fontsize, color='gray') # for the superior plot put_colorbar = True # make the plots plots = [] for i, cut_chunks in enumerate(grouper(cuts, n_cols)): ax = plt.subplot(gs[i]) cut_chunks = [cut for cut in cut_chunks if cut is not None] try: p = plot_func(_img, display_mode=cut_dir, cut_coords=cut_chunks, colorbar=put_colorbar, figure=fig, axes=ax, **kwargs) except IndexError: logging.warning('Could not plot for coords {}.'.format(cut_chunks)) finally: put_colorbar = False plots.append(p) for p in plots: p.close() return fig
def plot_defaced(bids_dir, subject_label, session=None, t2w=None): """ Plot brainmask created from original non-defaced image on defaced image to evaluate defacing performance. Parameters ---------- bids_dir : str Path to BIDS root directory. subject_label : str Label of subject to be plotted (without 'sub-'). session : str, optional If multiple sessions exist, create one plot per session. session : bool, optional If T2w image exists, create a plot for defaced T2w. """ from bids import BIDSLayout from glob import glob from os.path import join as opj from matplotlib.pyplot import figure import matplotlib.pyplot as plt from nilearn.plotting import find_cut_slices, plot_stat_map layout = BIDSLayout(bids_dir) bidsonym_path = opj(bids_dir, 'sourcedata/bidsonym/sub-%s' % subject_label) if session is not None: defaced_t1w = layout.get(subject=subject_label, extension='nii.gz', suffix='T1w', return_type='filename', session=session) else: defaced_t1w = layout.get(subject=subject_label, extension='nii.gz', suffix='T1w', return_type='filename') for t1w in defaced_t1w: brainmask_t1w = glob( opj( bids_dir, 'sourcedata/bidsonym/sub-%s' % subject_label, t1w[t1w.rfind('/') + 1:t1w.rfind('.nii')] + '_brainmask_desc-nondeid.nii.gz'))[0] fig = figure(figsize=(15, 5)) plt.subplots_adjust(left=0, bottom=0, right=1, top=1, wspace=-0.2, hspace=0) for i, e in enumerate(['x', 'y', 'z']): ax = fig.add_subplot(3, 1, i + 1) cuts = find_cut_slices(t1w, direction=e, n_cuts=12) plot_stat_map(brainmask_t1w, bg_img=t1w, display_mode=e, cut_coords=cuts, annotate=False, dim=-1, axes=ax, colorbar=False) plt.savefig( opj( bidsonym_path, t1w[t1w.rfind('/') + 1:t1w.rfind('.nii')] + '_desc-brainmaskdeid.png')) if t2w is not None: if session is not None: defaced_t2w = layout.get(subject=subject_label, extension='nii.gz', suffix='T2w', return_type='filename', session=session) else: defaced_t2w = layout.get(subject=subject_label, extension='nii.gz', suffix='T2w', return_type='filename') for t2w in defaced_t2w: brainmask_t2w = glob( opj( bids_dir, 'sourcedata/bidsonym/sub-%s' % subject_label, t2w[t2w.rfind('/') + 1:t2w.rfind('.nii')] + '_brainmask_desc-nondeid.nii.gz'))[0] for i, e in enumerate(['x', 'y', 'z']): ax = fig.add_subplot(3, 1, i + 1) cuts = find_cut_slices(t2w, direction=e, n_cuts=12) plot_stat_map(brainmask_t2w, bg_img=t2w, display_mode=e, cut_coords=cuts, annotate=False, dim=-1, axes=ax, colorbar=False) plt.savefig( opj( bids_dir, 'sourcedata/bidsonym/sub-%s' % subject_label, t2w[t2w.rfind('/') + 1:t2w.rfind('.nii')] + '_desc-brainmaskdeid.png')) return (t1w, t2w)
fignum = 411 if options.anat else 311 #plt.subplot(211) if options.anat: ax = fig.add_subplot(fignum) plotting.plot_anat(background_img, figure=fig, axes=ax, dim=-1) fignum += 1 #plotting.plot_anat(background_img, dim=-1) ax = fig.add_subplot(fignum + 0) # Workaround of a bug in nilearn import numbers if isinstance(nslices, numbers.Number): cuts = plotting.find_cut_slices(background_img, direction='z', n_cuts=nslices, spacing='auto') if len(set(cuts)) != nslices: nslices = cut_coords display = plotting.plot_anat(background_img, display_mode='z', cut_coords=nslices, figure=fig, axes=ax, dim=-1) #display = plotting.plot_anat(background_img, display_mode='z', cut_coords=nslices) display.add_overlay(gm_img, alpha=alpha_overlay, cmap=plt.cm.Greens, colorbar=True)