code: def plot_carpet(
      img,
      mask_img=None,
      mask_labels=None,
      t_r=None,
      detrend=True,
      output_file=None,
      figure=None,
      axes=None,
      vmin=None,
      vmax=None,
      title=None,
      cmap="gray",
      cmap_labels=plt.cm.gist_ncar,
      standardize=True,
  ):
      """Plot an image representation of :term:`voxel` intensities across time.
  
      This figure is also known as a "grayplot" or "Power plot".
  
      Parameters
      ----------
      %(img)s
          4D image.
  
      mask_img : Niimg-like object or None, default=None
          Limit plotted voxels to those inside the provided mask.
          If a 3D atlas is provided, voxels will be grouped by atlas
          value and a colorbar will be added to the left side of the figure
          with atlas labels.
          If not specified, a new mask will be derived from data.
          See :ref:`extracting_data`.
  
      mask_labels : :obj:`dict`, optional
          If ``mask_img`` corresponds to an atlas, then this dictionary maps
          values from the ``mask_img`` to labels. Dictionary keys are labels
          and values are values within the atlas.
      %(t_r)s
  
          .. note::
              If ``t_r`` is not provided, it will be inferred from ``img``'s
              header (``img.header.get_zooms()[-1]``).
  
          .. versionadded:: 0.9.1
              Prior to this, ``t_r`` would be inferred from ``img`` without
              user input.
  
      detrend : :obj:`bool`, default=True
          Detrend and z-score the data prior to plotting.
      %(output_file)s
      %(figure)s
      %(axes)s
      %(vmin)s
      %(vmax)s
      %(title)s
      %(cmap)s
  
          Default=`gray`.
  
      cmap_labels : :class:`matplotlib.colors.Colormap`, or :obj:`str`, \
                    default=`plt.cm.gist_ncar`
          If ``mask_img`` corresponds to an atlas, then cmap_labels
          can be used to define the colormap for coloring the labels placed
          on the side of the carpet plot.
  
      %(standardize)s
  
          .. note::
  
              Added to control passing value to `standardize` of ``signal.clean``
              to call new behavior since passing "zscore" or True (default) is
              deprecated. This parameter will be deprecated in version 0.13 and
              removed in version 0.15.
  
      Returns
      -------
      figure : :class:`matplotlib.figure.Figure`
          Figure object with carpet plot.
  
      Notes
      -----
      This figure was originally developed in :footcite:t:`Power2017`.
  
      In cases of long acquisitions (>800 volumes), the data will be downsampled
      to have fewer than 800 volumes before being plotted.
  
      References
      ----------
      .. footbibliography::
  
      """
      img = _utils.check_niimg_4d(img, dtype="auto")
  
      # Define TR and number of frames
      t_r = t_r or img.header.get_zooms()[-1]
      n_tsteps = img.shape[-1]
  
      if mask_img is None:
          mask_img = compute_epi_mask(img)
      else:
          mask_img = _utils.check_niimg_3d(mask_img, dtype="auto")
  
      is_atlas = len(np.unique(mask_img.get_fdata())) > 2
      if is_atlas:
          background_label = 0
  
          atlas_img_res = resample_to_img(
              mask_img,
              img,
              interpolation="nearest",
          )
          atlas_bin = math_img(
              f"img != {background_label}",
              img=atlas_img_res,
          )
          masker = NiftiMasker(atlas_bin, target_affine=img.affine)
  
          data = masker.fit_transform(img)
          atlas_values = masker.transform(atlas_img_res)
          atlas_values = np.squeeze(atlas_values)
  
          if mask_labels:
              label_dtype = type(list(mask_labels.values())[0])
              if label_dtype != atlas_values.dtype:
                  print(f"Coercing atlas_values to {label_dtype}")
                  atlas_values = atlas_values.astype(label_dtype)
  
          # Sort data and atlas by atlas values
          order = np.argsort(atlas_values)
          order = np.squeeze(order)
          atlas_values = atlas_values[order]
          data = data[:, order]
      else:
          data = apply_mask(img, mask_img)
  
      # Detrend and standardize data
      if detrend:
          data = clean(
              data, t_r=t_r, detrend=True, standardize=standardize
          )
  
      if figure is None:
          if not axes:
              figsize = (10, 5)
              figure = plt.figure(figsize=figsize)
          else:
              figure = axes.figure
  
      if axes is None:
          axes = figure.add_subplot(1, 1, 1)
      else:
          assert (
              axes.figure is figure
          ), "The axes passed are not in the figure"
  
      # Determine vmin and vmax based on the full data
      std = np.mean(data.std(axis=0))
      default_vmin = data.mean() - (2 * std)
      default_vmax = data.mean() + (2 * std)
  
      # Avoid segmentation faults for long acquisitions by decimating the data
      LONG_CUTOFF = 800
      # Get smallest power of 2 greater than the number of volumes divided by the
      # cutoff, to determine how much to decimate (downsample) the data.
      n_decimations = int(
          np.ceil(np.log2(np.ceil(n_tsteps / LONG_CUTOFF)))
      )
      data = data[:: 2**n_decimations, :]
  
      if is_atlas:
          # Define nested GridSpec
          legend = False
          wratios = [2, 100, 20]
          gs = mgs.GridSpecFromSubplotSpec(
              1,
              2 + int(legend),
              subplot_spec=axes,
              width_ratios=wratios[: 2 + int(legend)],
              wspace=0.0,
          )
  
          ax0 = plt.subplot(gs[0])
          ax0.set_xticks([])
          ax0.imshow(
              atlas_values[:, np.newaxis],
              interpolation="none",
              aspect="auto",
              cmap=cmap_labels,
          )
          if mask_labels:
              # Add labels to middle of each associated band
              mask_labels_inv = {v: k for k, v in mask_labels.items()}
              ytick_locs = [
                  np.mean(np.where(atlas_values == i)[0])
                  for i in np.unique(atlas_values)
              ]
              ax0.set_yticks(ytick_locs)
              ax0.set_yticklabels(
                  [mask_labels_inv[i] for i in np.unique(atlas_values)]
              )
          else:
              ax0.set_yticks([])
  
          # Carpet plot
          if compare_version(matplotlib.__version__, ">=", "3.8.0rc1"):
              axes.remove()  # remove axes for newer versions of mpl
          axes = plt.subplot(
              gs[1]
          )  # overwrites axes with older versions of mpl
          axes.imshow(
              data.T,
              interpolation="nearest",
              aspect="auto",
              cmap=cmap,
              vmin=vmin or default_vmin,
              vmax=vmax or default_vmax,
          )
          ax0.tick_params(axis="both", which="both", length=0)
      else:
          axes.imshow(
              data.T,
              interpolation="nearest",
              aspect="auto",
              cmap=cmap,
              vmin=vmin or default_vmin,
              vmax=vmax or default_vmax,
          )
  
      axes.grid(False)
      axes.set_yticks([])
      axes.set_yticklabels([])
  
      # Set 10 frame markers in X axis
      interval = max(
          (int(data.shape[0] + 1) // 10, int(data.shape[0] + 1) // 5, 1)
      )
      xticks = list(range(0, data.shape[0])[::interval])
      axes.set_xticks(xticks)
      axes.set_xlabel("time (s)")
  
      if title:
          axes.set_title(title)
  
      labels = t_r * (np.array(xticks))
      labels *= 2**n_decimations
      axes.set_xticklabels([f"{t:.02f}" for t in labels.tolist()])
  
      # Remove and redefine spines
      for side in ["top", "right"]:
          # Toggle the spine objects
          axes.spines[side].set_color("none")
          axes.spines[side].set_visible(False)
  
      axes.xaxis.set_ticks_position("bottom")
      axes.spines["bottom"].set_position(("outward", 10))
  
      if not mask_labels:
          axes.yaxis.set_ticks_position("left")
          buffer = 20 if is_atlas else 10
          axes.spines["left"].set_position(("outward", buffer))
          axes.set_ylabel("voxels")
  
      if output_file is not None:
          figure.savefig(output_file)
          plt.close(figure)
          figure = None
  
      return figure
  
imports: import collections.abc
  import functools
  import numbers
  import os
  import warnings
  import matplotlib
  import matplotlib.pyplot
  import numpy
  from matplotlib import gridspec
  from matplotlib.colors import LinearSegmentedColormap
  from nibabel.spatialimages import SpatialImage
  from scipy import stats
  from scipy.ndimage import binary_fill_holes
  from nilearn.image.resampling import reorder_img
  from nilearn.maskers import NiftiMasker
  from nilearn.plotting.displays import get_projector, get_slicer
  from nilearn.plotting.displays._slicers import _get_cbar_ticks
  from ..None import _utils
  from .._utils import compare_version, fill_doc
  from .._utils.extmath import fast_abs_percentile
  from .._utils.ndimage import get_border_data
  from .._utils.niimg import safe_get_data
  from .._utils.numpy_conversions import as_ndarray
  from .._utils.param_validation import check_threshold
  from ..datasets import load_mni152_template
  from ..image import get_data, iter_img, math_img, new_img_like, resample_to_img
  from ..masking import apply_mask, compute_epi_mask
  from ..signal import clean
  from .None import cm
label_desc: Use image node_id 16 for calling a global function with example usage: plot_carpet(img, mask_img, mask_labels, t_r, detrend, output_file, figure, axes, vmin, vmax, title, cmap, cmap_labels, standardize) and returns: figure