diff --git a/nireports/reportlets/modality/func.py b/nireports/reportlets/modality/func.py index c7fad66..385d903 100644 --- a/nireports/reportlets/modality/func.py +++ b/nireports/reportlets/modality/func.py @@ -92,7 +92,7 @@ def __init__( def plot(self, figure=None, out_file=None, fontsize=24): """Main plotter""" - plt.rcParams.update({"font.size": 22}) + plt.rcParams.update({"font.size": fontsize}) nconfounds = len(self.confounds) nspikes = len(self.spikes) diff --git a/nireports/reportlets/nuisance.py b/nireports/reportlets/nuisance.py index fc76d09..4bc3f5e 100644 --- a/nireports/reportlets/nuisance.py +++ b/nireports/reportlets/nuisance.py @@ -34,7 +34,6 @@ import pandas as pd import seaborn as sns from matplotlib.backends.backend_pdf import FigureCanvasPdf as FigureCanvas -from matplotlib.colorbar import ColorbarBase from matplotlib.colors import Normalize from matplotlib.gridspec import GridSpec, GridSpecFromSubplotSpec @@ -325,14 +324,19 @@ def plot_carpet( # If subplot is not defined if subplot is None: figure, allaxes = plt.subplots(figsize=(19.2, 10)) - allaxes.spines[:].set_visible(False) - allaxes.spines[:].set_color("none") - allaxes.get_xaxis().set_visible(False) - allaxes.get_yaxis().set_visible(False) subplot = allaxes.get_subplotspec() - fontsize = fontsize or 24 else: - figure = plt.gcf() + subplotax = plt.subplot(subplot) + figure = subplotax.get_figure() + + # Remove spines and ticks in all figure's axes + for ax in figure.axes: + ax.spines[:].set_visible(False) + ax.spines[:].set_color("none") + ax.get_xaxis().set_visible(False) + ax.get_yaxis().set_visible(False) + + fontsize = fontsize or 24 # Length before decimation n_trs = data.shape[-1] - drop_trs @@ -609,26 +613,6 @@ def spikesplot( return ax -def spikesplot_cb(position, cmap="viridis", fig=None): - # Add colorbar - if fig is None: - fig = plt.gcf() - - cax = fig.add_axes(position) - cb = ColorbarBase( - cax, - cmap=mpl.colormaps[cmap], - spacing="proportional", - orientation="horizontal", - drawedges=False, - ) - cb.set_ticks([0, 0.5, 1.0]) - cb.set_ticklabels(["Inferior", "(axial slice)", "Superior"]) - cb.outline.set_linewidth(0) - cb.ax.xaxis.set_tick_params(width=0) - return cax - - def confoundplot( tseries, gs_ts, @@ -897,8 +881,7 @@ def confounds_correlation_plot( corr = corr.loc[features, features] np.fill_diagonal(corr.values, 0) - if figure is None: - plt.figure(figsize=(15, 5)) + figure = figure if figure is not None else plt.figure(figsize=(15, 5)) gs = GridSpec(1, 21) ax0 = plt.subplot(gs[0, :10]) ax1 = plt.subplot(gs[0, 11:]) @@ -939,7 +922,6 @@ def confounds_correlation_plot( ax1.spines[side].set_visible(False) if output_file is not None: - figure = plt.gcf() figure.savefig(output_file, bbox_inches="tight") plt.close(figure) figure = None @@ -1115,9 +1097,7 @@ def plot_raincloud( df_clip = df.copy(deep=True) df_clip[feature] = df[feature].clip(lower=lower_limit_value, upper=upper_limit_value) - if figure is None: - plt.figure(figsize=(7, 5)) - + figure = figure if figure is not None else plt.figure(figsize=(7, 5)) gs = GridSpec(1, 1) ax = plt.subplot(gs[0, 0]) @@ -1211,7 +1191,6 @@ def plot_raincloud( ) if output_file is not None: - figure = plt.gcf() plt.tight_layout() figure.savefig(output_file, bbox_inches="tight") plt.close(figure) diff --git a/nireports/reportlets/xca.py b/nireports/reportlets/xca.py index 97575fd..6826f0c 100644 --- a/nireports/reportlets/xca.py +++ b/nireports/reportlets/xca.py @@ -310,6 +310,7 @@ def compcor_variance_plot( elif len(decompositions) > 1: fig, ax = plt.subplots(1, len(decompositions), figsize=(5 * len(decompositions), 5)) else: + fig = plt.gcf() ax = [plt.axes()] for m, (source, mask) in enumerate(decompositions): @@ -367,8 +368,6 @@ def compcor_variance_plot( ax[m].spines[side].set_visible(False) if output_file is not None: - if fig is None: - fig = plt.gcf() fig.savefig(output_file, bbox_inches="tight") fig.clf() fig = None diff --git a/nireports/tests/test_interfaces.py b/nireports/tests/test_interfaces.py index d027c0e..a31fc8a 100644 --- a/nireports/tests/test_interfaces.py +++ b/nireports/tests/test_interfaces.py @@ -25,8 +25,11 @@ import os from shutil import copy +import nibabel as nb +import numpy as np import pytest +from nireports.interfaces.fmri import FMRISummary from nireports.interfaces.nuisance import ( CompCorVariancePlot, ConfoundsCorrelationPlot, @@ -96,3 +99,43 @@ def test_RaincloudPlot(orient, density, tmp_path): mark_nans=mark_nans, ) _smoke_test_report(rc_rpt, f"raincloud_orient-{orient}_density-{density}.svg") + + +def test_FMRISummary(testdata_path, tmp_path, outdir): + """Exercise the FMRISummary interface.""" + rng = np.random.default_rng(2010) + + in_func = testdata_path / "sub-ds205s03_task-functionallocalizer_run-01_bold_volreg.nii.gz" + ntimepoints = nb.load(in_func).shape[-1] + + np.savetxt( + tmp_path / "fd.txt", + rng.normal(0.2, 0.2, ntimepoints - 1).T, + ) + + np.savetxt( + tmp_path / "outliers.txt", + rng.normal(0.2, 0.2, ntimepoints - 1).T, + ) + + np.savetxt( + tmp_path / "dvars.txt", + rng.normal(0.2, 0.2, (ntimepoints - 1, 2)), + ) + + interface = FMRISummary( + in_func=str(in_func), + in_segm=str( + testdata_path / "sub-ds205s03_task-functionallocalizer_run-01_bold_parc.nii.gz" + ), + fd=str(tmp_path / "fd.txt"), + outliers=str(tmp_path / "outliers.txt"), + dvars=str(tmp_path / "dvars.txt"), + ) + + result = interface.run() + + if outdir is not None: + from shutil import copy + + copy(result.outputs.out_file, outdir / "fmriplot_nipype.svg")