Plot pseudodepths for the measurements. If grid is given, then the
    actual electrode positions are used, and the parameter 'spacing' is
    ignored'

    Parameters
    ----------
    configs: :class:`numpy.ndarray`
        Nx4 array containing the quadrupoles for different measurements
    nr_electrodes: int
        The overall number of electrodes of the dataset. This is used to plot
        the surface electrodes
    spacing: float, optional
        assumed distance between electrodes. Default=1
    grid: crtomo.grid.crt_grid instance, optional
        grid instance. Used to infer real electrode positions
    ctypes: list of strings, optional
        a list of configuration types that will be plotted. All
        configurations that can not be sorted into these types will not be
        plotted! Possible types:

        * dd
        * schlumberger

    dd_merge: bool, optional
        if True, merge all skips. Otherwise, generate individual plots for
        each skip

    Returns
    -------
    figs: matplotlib.figure.Figure instance or list of Figure instances
        if only one type was plotted, then the figure instance is returned.
        Otherwise, return a list of figure instances.
    axes: axes object or list of axes ojects
        plot axes

    Examples
    --------

    .. plot::
        :include-source:

        from reda.plotters.plots2d import plot_pseudodepths
        # define a few measurements
        import numpy as np
        configs = np.array((
            (1, 2, 4, 3),
            (1, 2, 5, 4),
            (1, 2, 6, 5),
            (2, 3, 5, 4),
            (2, 3, 6, 5),
            (3, 4, 6, 5),
        ))
        # plot
        fig, axes = plot_pseudodepths(configs, nr_electrodes=6, spacing=1,
                                      ctypes=['dd', ])

    .. plot::
        :include-source:

        from reda.plotters.plots2d import plot_pseudodepths
        # define a few measurements
        import numpy as np
        configs = np.array((
            (4, 7, 5, 6),
            (3, 8, 5, 6),
            (2, 9, 5, 6),
            (1, 10, 5, 6),
        ))
        # plot
        fig, axes = plot_pseudodepths(configs, nr_electrodes=10, spacing=1,
                                      ctypes=['schlumberger', ])

def plot_pseudodepths(configs, nr_electrodes, spacing=1, grid=None,
                      ctypes=None, dd_merge=False, **kwargs):
    """Plot pseudodepths for the measurements. If grid is given, then the
    actual electrode positions are used, and the parameter 'spacing' is
    ignored'

    Parameters
    ----------
    configs: :class:`numpy.ndarray`
        Nx4 array containing the quadrupoles for different measurements
    nr_electrodes: int
        The overall number of electrodes of the dataset. This is used to plot
        the surface electrodes
    spacing: float, optional
        assumed distance between electrodes. Default=1
    grid: crtomo.grid.crt_grid instance, optional
        grid instance. Used to infer real electrode positions
    ctypes: list of strings, optional
        a list of configuration types that will be plotted. All
        configurations that can not be sorted into these types will not be
        plotted! Possible types:

        * dd
        * schlumberger

    dd_merge: bool, optional
        if True, merge all skips. Otherwise, generate individual plots for
        each skip

    Returns
    -------
    figs: matplotlib.figure.Figure instance or list of Figure instances
        if only one type was plotted, then the figure instance is returned.
        Otherwise, return a list of figure instances.
    axes: axes object or list of axes ojects
        plot axes

    Examples
    --------

    .. plot::
        :include-source:

        from reda.plotters.plots2d import plot_pseudodepths
        # define a few measurements
        import numpy as np
        configs = np.array((
            (1, 2, 4, 3),
            (1, 2, 5, 4),
            (1, 2, 6, 5),
            (2, 3, 5, 4),
            (2, 3, 6, 5),
            (3, 4, 6, 5),
        ))
        # plot
        fig, axes = plot_pseudodepths(configs, nr_electrodes=6, spacing=1,
                                      ctypes=['dd', ])

    .. plot::
        :include-source:

        from reda.plotters.plots2d import plot_pseudodepths
        # define a few measurements
        import numpy as np
        configs = np.array((
            (4, 7, 5, 6),
            (3, 8, 5, 6),
            (2, 9, 5, 6),
            (1, 10, 5, 6),
        ))
        # plot
        fig, axes = plot_pseudodepths(configs, nr_electrodes=10, spacing=1,
                                      ctypes=['schlumberger', ])

    """
    # for each configuration type we have different ways of computing
    # pseudodepths
    pseudo_d_functions = {
        'dd': _pseudodepths_dd_simple,
        'schlumberger': _pseudodepths_schlumberger,
        'wenner': _pseudodepths_wenner,
    }

    titles = {
        'dd': 'dipole-dipole configurations',
        'schlumberger': 'Schlumberger configurations',
        'wenner': 'Wenner configurations',
    }

    # sort the configurations into the various types of configurations
    only_types = ctypes or ['dd', ]
    results = fT.filter(configs, settings={'only_types': only_types, })

    # loop through all measurement types
    figs = []
    axes = []
    for key in sorted(results.keys()):
        print('plotting: ', key)
        if key == 'not_sorted':
            continue
        index_dict = results[key]
        # it is possible that we want to generate multiple plots for one
        # type of measurement, i.e., to separate skips of dipole-dipole
        # measurements. Therefore we generate two lists:
        # 1) list of list of indices to plot
        # 2) corresponding labels
        if key == 'dd' and not dd_merge:
            plot_list = []
            labels_add = []
            for skip in sorted(index_dict.keys()):
                plot_list.append(index_dict[skip])
                labels_add.append(' - skip {0}'.format(skip))
        else:
            # merge all indices
            plot_list = [np.hstack(index_dict.values()), ]
            print('schlumberger', plot_list)
            labels_add = ['', ]

        grid = None
        # generate plots
        for indices, label_add in zip(plot_list, labels_add):
            if len(indices) == 0:
                continue
            ddc = configs[indices]
            px, pz = pseudo_d_functions[key](ddc, spacing, grid)

            fig, ax = plt.subplots(figsize=(15 / 2.54, 5 / 2.54))
            ax.scatter(px, pz, color='k', alpha=0.5)

            # plot electrodes
            if grid is not None:
                electrodes = grid.get_electrode_positions()
                ax.scatter(
                    electrodes[:, 0],
                    electrodes[:, 1],
                    color='b',
                    label='electrodes', )
            else:
                ax.scatter(
                    np.arange(0, nr_electrodes) * spacing,
                    np.zeros(nr_electrodes),
                    color='b',
                    label='electrodes', )
            ax.set_title(titles[key] + label_add)
            ax.set_aspect('equal')
            ax.set_xlabel('x [m]')
            ax.set_ylabel('x [z]')

            fig.tight_layout()
            figs.append(fig)
            axes.append(ax)

    if len(figs) == 1:
        return figs[0], axes[0]
    else:
        return figs, axes