# Buggy code
def plot_ica_components(
    ica,
    picks=None,
    ch_type=None,
    res=64,
    layout=None,
    vmin=None,
    vmax=None,
    cmap="RdBu_r",
    sensors=True,
    colorbar=False,
    title=None,
    show=True,
    outlines="head",
    contours=6,
    image_interp="bilinear",
    head_pos=None,
):
    """Project unmixing matrix on interpolated sensor topogrpahy.

    Parameters
    ----------
    ica : instance of mne.preprocessing.ICA
        The ICA solution.
    picks : int | array-like | None
        The indices of the sources to be plotted.
        If None all are plotted in batches of 20.
    ch_type : 'mag' | 'grad' | 'planar1' | 'planar2' | 'eeg' | None
        The channel type to plot. For 'grad', the gradiometers are
        collected in pairs and the RMS for each pair is plotted.
        If None, then channels are chosen in the order given above.
    res : int
        The resolution of the topomap image (n pixels along each side).
    layout : None | Layout
        Layout instance specifying sensor positions (does not need to
        be specified for Neuromag data). If possible, the correct layout is
        inferred from the data.
    vmin : float | callable | None
        The value specifying the lower bound of the color range.
        If None, and vmax is None, -vmax is used. Else np.min(data).
        If callable, the output equals vmin(data). Defaults to None.
    vmax : float | callable | None
        The value specifying the upper bound of the color range.
        If None, the maximum absolute value is used. If callable, the output
        equals vmax(data). Defaults to None.
    cmap : matplotlib colormap
        Colormap.
    sensors : bool | str
        Add markers for sensor locations to the plot. Accepts matplotlib
        plot format string (e.g., 'r+' for red plusses). If True, a circle
        will be used (via .add_artist). Defaults to True.
    colorbar : bool
        Plot a colorbar.
    title : str | None
        Title to use.
    show : bool
        Show figure if True.
    outlines : 'head' | 'skirt' | dict | None
        The outlines to be drawn. If 'head', the default head scheme will be
        drawn. If 'skirt' the head scheme will be drawn, but sensors are
        allowed to be plotted outside of the head circle. If dict, each key
        refers to a tuple of x and y positions, the values in 'mask_pos' will
        serve as image mask, and the 'autoshrink' (bool) field will trigger
        automated shrinking of the positions due to points outside the outline.
        Alternatively, a matplotlib patch object can be passed for advanced
        masking options, either directly or as a function that returns patches
        (required for multi-axis plots). If None, nothing will be drawn.
        Defaults to 'head'.
    contours : int | False | None
        The number of contour lines to draw. If 0, no contours will be drawn.
    image_interp : str
        The image interpolation to be used. All matplotlib options are
        accepted.
    head_pos : dict | None
        If None (default), the sensors are positioned such that they span
        the head circle. If dict, can have entries 'center' (tuple) and
        'scale' (tuple) for what the center and scale of the head should be
        relative to the electrode locations.

    Returns
    -------
    fig : instance of matplotlib.pyplot.Figure or list
        The figure object(s).
    """
    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid import make_axes_locatable
    from ..channels import _get_ch_type

    if picks is None:  # plot components by sets of 20
        ch_type = _get_ch_type(ica, ch_type)
        n_components = ica.mixing_matrix_.shape[1]
        p = 20
        figs = []
        for k in range(0, n_components, p):
            picks = range(k, min(k + p, n_components))
            fig = plot_ica_components(
                ica,
                picks=picks,
                ch_type=ch_type,
                res=res,
                layout=layout,
                vmax=vmax,
                cmap=cmap,
                sensors=sensors,
                colorbar=colorbar,
                title=title,
                show=show,
                outlines=outlines,
                contours=contours,
                image_interp=image_interp,
            )
            figs.append(fig)
        return figs
    elif np.isscalar(picks):
        picks = [picks]
    ch_type = _get_ch_type(ica, ch_type)

    data = np.dot(
        ica.mixing_matrix_[:, picks].T, ica.pca_components_[: ica.n_components_]
    )

    if ica.info is None:
        raise RuntimeError(
            "The ICA's measurement info is missing. Please "
            "fit the ICA or add the corresponding info object."
        )

    data_picks, pos, merge_grads, names, _ = _prepare_topo_plot(ica, ch_type, layout)
    pos, outlines = _check_outlines(pos, outlines, head_pos)
    if outlines not in (None, "head"):
        image_mask, pos = _make_image_mask(outlines, pos, res)
    else:
        image_mask = None

    data = np.atleast_2d(data)
    data = data[:, data_picks]

    # prepare data for iteration
    fig, axes = _prepare_trellis(len(data), max_col=5)
    if title is None:
        title = "ICA components"
    fig.suptitle(title)

    if merge_grads:
        from ..channels.layout import _merge_grad_data
    for ii, data_, ax in zip(picks, data, axes):
        ax.set_title("IC #%03d" % ii, fontsize=12)
        data_ = _merge_grad_data(data_) if merge_grads else data_
        vmin_, vmax_ = _setup_vmin_vmax(data_, vmin, vmax)
        im = plot_topomap(
            data_.flatten(),
            pos,
            vmin=vmin_,
            vmax=vmax_,
            res=res,
            axes=ax,
            cmap=cmap,
            outlines=outlines,
            image_mask=image_mask,
            contours=contours,
            image_interp=image_interp,
            show=False,
        )[0]
        if colorbar:
            divider = make_axes_locatable(ax)
            cax = divider.append_axes("right", size="5%", pad=0.05)
            cbar = plt.colorbar(im, cax=cax, format="%3.2f", cmap=cmap)
            cbar.ax.tick_params(labelsize=12)
            cbar.set_ticks((vmin_, vmax_))
            cbar.ax.set_title("AU", fontsize=10)
        _hide_frame(ax)
    tight_layout(fig=fig)
    fig.subplots_adjust(top=0.95)
    fig.canvas.draw()
    plt_show(show)
    return fig


# Traceback (ValueError)
n [15]: Traceback (most recent call last):
File "/tsi/doctorants/mainak/anaconda/lib/python2.7/site-packages/matplotlib/backends/backend_qt5.py", line 291, in mouseReleaseEvent
FigureCanvasBase.button_release_event(self, x, y, button)
File "/tsi/doctorants/mainak/anaconda/lib/python2.7/site-packages/matplotlib/backend_bases.py", line 1891, in button_release_event
self.callbacks.process(s, event)
File "/tsi/doctorants/mainak/anaconda/lib/python2.7/site-packages/matplotlib/cbook.py", line 533, in process
proxy(*args, **kwargs)
File "/tsi/doctorants/mainak/anaconda/lib/python2.7/site-packages/matplotlib/cbook.py", line 408, in __call__
return mtd(*args, **kwargs)
File "/tsi/doctorants/mainak/anaconda/lib/python2.7/site-packages/matplotlib/widgets.py", line 1250, in release
self.onselect(vmin, vmax)
File "/tsi/doctorants/mainak/mne-python/mne/viz/evoked.py", line 90, in _butterfly_onselect
layout=None)
File "/tsi/doctorants/mainak/mne-python/mne/viz/topomap.py", line 49, in _prepare_topo_plot
picks, pos = _pair_grad_sensors(info, layout)
File "/tsi/doctorants/mainak/mne-python/mne/channels/layout.py", line 689, in _pair_grad_sensors
raise ValueError("No 'grad' channel pairs found.")
ValueError: No 'grad' channel pairs found.

# Fixed code
def plot_ica_components(
    ica,
    picks=None,
    ch_type=None,
    res=64,
    layout=None,
    vmin=None,
    vmax=None,
    cmap="RdBu_r",
    sensors=True,
    colorbar=False,
    title=None,
    show=True,
    outlines="head",
    contours=6,
    image_interp="bilinear",
    head_pos=None,
):
    """Project unmixing matrix on interpolated sensor topogrpahy.

    Parameters
    ----------
    ica : instance of mne.preprocessing.ICA
        The ICA solution.
    picks : int | array-like | None
        The indices of the sources to be plotted.
        If None all are plotted in batches of 20.
    ch_type : 'mag' | 'grad' | 'planar1' | 'planar2' | 'eeg' | None
        The channel type to plot. For 'grad', the gradiometers are
        collected in pairs and the RMS for each pair is plotted.
        If None, then channels are chosen in the order given above.
    res : int
        The resolution of the topomap image (n pixels along each side).
    layout : None | Layout
        Layout instance specifying sensor positions (does not need to
        be specified for Neuromag data). If possible, the correct layout is
        inferred from the data.
    vmin : float | callable | None
        The value specifying the lower bound of the color range.
        If None, and vmax is None, -vmax is used. Else np.min(data).
        If callable, the output equals vmin(data). Defaults to None.
    vmax : float | callable | None
        The value specifying the upper bound of the color range.
        If None, the maximum absolute value is used. If callable, the output
        equals vmax(data). Defaults to None.
    cmap : matplotlib colormap | (colormap, bool) | 'interactive' | None
        Colormap to use. If tuple, the first value indicates the colormap to
        use and the second value is a boolean defining interactivity. In
        interactive mode the colors are adjustable by clicking and dragging the
        colorbar with left and right mouse button. Left mouse button moves the
        scale up and down and right mouse button adjusts the range. Hitting
        space bar resets the range. Up and down arrows can be used to change
        the colormap. If None, 'Reds' is used for all positive data,
        otherwise defaults to 'RdBu_r'. If 'interactive', translates to
        (None, True). Defaults to 'RdBu_r'.

        .. warning::  Interactive mode works smoothly only for a small amount
            of topomaps.

    sensors : bool | str
        Add markers for sensor locations to the plot. Accepts matplotlib
        plot format string (e.g., 'r+' for red plusses). If True, a circle
        will be used (via .add_artist). Defaults to True.
    colorbar : bool
        Plot a colorbar.
    title : str | None
        Title to use.
    show : bool
        Show figure if True.
    outlines : 'head' | 'skirt' | dict | None
        The outlines to be drawn. If 'head', the default head scheme will be
        drawn. If 'skirt' the head scheme will be drawn, but sensors are
        allowed to be plotted outside of the head circle. If dict, each key
        refers to a tuple of x and y positions, the values in 'mask_pos' will
        serve as image mask, and the 'autoshrink' (bool) field will trigger
        automated shrinking of the positions due to points outside the outline.
        Alternatively, a matplotlib patch object can be passed for advanced
        masking options, either directly or as a function that returns patches
        (required for multi-axis plots). If None, nothing will be drawn.
        Defaults to 'head'.
    contours : int | False | None
        The number of contour lines to draw. If 0, no contours will be drawn.
    image_interp : str
        The image interpolation to be used. All matplotlib options are
        accepted.
    head_pos : dict | None
        If None (default), the sensors are positioned such that they span
        the head circle. If dict, can have entries 'center' (tuple) and
        'scale' (tuple) for what the center and scale of the head should be
        relative to the electrode locations.

    Returns
    -------
    fig : instance of matplotlib.pyplot.Figure or list
        The figure object(s).
    """
    import matplotlib.pyplot as plt
    from mpl_toolkits.axes_grid import make_axes_locatable
    from ..channels import _get_ch_type

    if picks is None:  # plot components by sets of 20
        ch_type = _get_ch_type(ica, ch_type)
        n_components = ica.mixing_matrix_.shape[1]
        p = 20
        figs = []
        for k in range(0, n_components, p):
            picks = range(k, min(k + p, n_components))
            fig = plot_ica_components(
                ica,
                picks=picks,
                ch_type=ch_type,
                res=res,
                layout=layout,
                vmax=vmax,
                cmap=cmap,
                sensors=sensors,
                colorbar=colorbar,
                title=title,
                show=show,
                outlines=outlines,
                contours=contours,
                image_interp=image_interp,
            )
            figs.append(fig)
        return figs
    elif np.isscalar(picks):
        picks = [picks]
    ch_type = _get_ch_type(ica, ch_type)

    if cmap == "interactive":
        cmap = ("RdBu_r", True)
    elif not isinstance(cmap, tuple):
        if len(picks) > 2:
            warn(
                "Disabling interactive colorbar for multiple axes. Turn "
                "interactivity on explicitly by passing cmap as a tuple."
            )
            cmap = (cmap, False)
        else:
            cmap = (cmap, True)
    data = np.dot(
        ica.mixing_matrix_[:, picks].T, ica.pca_components_[: ica.n_components_]
    )

    if ica.info is None:
        raise RuntimeError(
            "The ICA's measurement info is missing. Please "
            "fit the ICA or add the corresponding info object."
        )

    data_picks, pos, merge_grads, names, _ = _prepare_topo_plot(ica, ch_type, layout)
    pos, outlines = _check_outlines(pos, outlines, head_pos)
    if outlines not in (None, "head"):
        image_mask, pos = _make_image_mask(outlines, pos, res)
    else:
        image_mask = None

    data = np.atleast_2d(data)
    data = data[:, data_picks]

    # prepare data for iteration
    fig, axes = _prepare_trellis(len(data), max_col=5)
    if title is None:
        title = "ICA components"
    fig.suptitle(title)

    if merge_grads:
        from ..channels.layout import _merge_grad_data
    for ii, data_, ax in zip(picks, data, axes):
        ax.set_title("IC #%03d" % ii, fontsize=12)
        data_ = _merge_grad_data(data_) if merge_grads else data_
        vmin_, vmax_ = _setup_vmin_vmax(data_, vmin, vmax)
        im = plot_topomap(
            data_.flatten(),
            pos,
            vmin=vmin_,
            vmax=vmax_,
            res=res,
            axes=ax,
            cmap=cmap[0],
            outlines=outlines,
            image_mask=image_mask,
            contours=contours,
            image_interp=image_interp,
            show=False,
        )[0]
        if colorbar:
            divider = make_axes_locatable(ax)
            cax = divider.append_axes("right", size="5%", pad=0.05)
            cbar = plt.colorbar(im, cax=cax, format="%3.2f", cmap=cmap)
            cbar.ax.tick_params(labelsize=12)
            cbar.set_ticks((vmin_, vmax_))
            cbar.ax.set_title("AU", fontsize=10)
            if cmap[1]:
                ax.CB = DraggableColorbar(cbar, im)
        _hide_frame(ax)
    tight_layout(fig=fig)
    fig.subplots_adjust(top=0.95)
    fig.canvas.draw()
    plt_show(show)
    return fig