def _add_data(self, plotter_cls, filename_or_obj, fmt={}, make_plot=True,
                  draw=False, mf_mode=False, ax=None, engine=None, delete=True,
                  share=False, clear=False, enable_post=None,
                  concat_dim=_concat_dim_default, load=False,
                  *args, **kwargs):
        """
        Extract data from a dataset and visualize it with the given plotter

        Parameters
        ----------
        plotter_cls: type
            The subclass of :class:`psyplot.plotter.Plotter` to use for
            visualization
        filename_or_obj: filename, :class:`xarray.Dataset` or data store
            The object (or file name) to open. If not a dataset, the
            :func:`psyplot.data.open_dataset` will be used to open a dataset
        fmt: dict
            Formatoptions that shall be when initializing the plot (you can
            however also specify them as extra keyword arguments)
        make_plot: bool
            If True, the data is plotted at the end. Otherwise you have to
            call the :meth:`psyplot.plotter.Plotter.initialize_plot` method or
            the :meth:`psyplot.plotter.Plotter.reinit` method by yourself
        %(InteractiveBase.start_update.parameters.draw)s
        mf_mode: bool
            If True, the :func:`psyplot.open_mfdataset` method is used.
            Otherwise we use the :func:`psyplot.open_dataset` method which can
            open only one single dataset
        ax: None, tuple (x, y[, z]) or (list of) matplotlib.axes.Axes
            Specifies the subplots on which to plot the new data objects.

            - If None, a new figure will be created for each created plotter
            - If tuple (x, y[, z]), `x` specifies the number of rows, `y` the
              number of columns and the optional third parameter `z` the
              maximal number of subplots per figure.
            - If :class:`matplotlib.axes.Axes` (or list of those, e.g. created
              by the :func:`matplotlib.pyplot.subplots` function), the data
              will be plotted on these subplots
        %(open_dataset.parameters.engine)s
        %(multiple_subplots.parameters.delete)s
        share: bool, fmt key or list of fmt keys
            Determines whether the first created plotter shares it's
            formatoptions with the others. If True, all formatoptions are
            shared. Strings or list of strings specify the keys to share.
        clear: bool
            If True, axes are cleared before making the plot. This is only
            necessary if the `ax` keyword consists of subplots with projection
            that differs from the one that is needed
        enable_post: bool
            If True, the :attr:`~psyplot.plotter.Plotter.post` formatoption is
            enabled and post processing scripts are allowed. If ``None``, this
            parameter is set to True if there is a value given for the `post`
            formatoption in `fmt` or `kwargs`
        %(xarray.open_mfdataset.parameters.concat_dim)s
            This parameter only does have an effect if `mf_mode` is True.
        load: bool
            If True, load the complete dataset into memory before plotting.
            This might be useful if the data of other variables in the dataset
            has to be accessed multiple times, e.g. for unstructured grids.
        %(ArrayList.from_dataset.parameters.no_base)s

        Other Parameters
        ----------------
        %(ArrayList.from_dataset.other_parameters.no_args_kwargs)s
        ``**kwargs``
            Any other dimension or formatoption that shall be passed to `dims`
            or `fmt` respectively.

        Returns
        -------
        Project
            The subproject that contains the new (visualized) data array"""
        if not isinstance(filename_or_obj, xarray.Dataset):
            if mf_mode:
                filename_or_obj = open_mfdataset(filename_or_obj,
                                                 engine=engine,
                                                 concat_dim=concat_dim)
            else:
                filename_or_obj = open_dataset(filename_or_obj,
                                               engine=engine)
        if load:
            old = filename_or_obj
            filename_or_obj = filename_or_obj.load()
            old.close()

        fmt = dict(fmt)
        possible_fmts = list(plotter_cls._get_formatoptions())
        additional_fmt, kwargs = utils.sort_kwargs(
            kwargs, possible_fmts)
        fmt.update(additional_fmt)
        if enable_post is None:
            enable_post = bool(fmt.get('post'))
        # create the subproject
        sub_project = self.from_dataset(filename_or_obj, **kwargs)
        sub_project.main = self
        sub_project.no_auto_update = not (
            not sub_project.no_auto_update or not self.no_auto_update)
        # create the subplots
        proj = plotter_cls._get_sample_projection()
        if isinstance(ax, tuple):
            axes = iter(multiple_subplots(
                *ax, n=len(sub_project), subplot_kw={'projection': proj}))
        elif ax is None or isinstance(ax, (mpl.axes.SubplotBase,
                                           mpl.axes.Axes)):
            axes = repeat(ax)
        else:
            axes = iter(ax)
        clear = clear or (isinstance(ax, tuple) and proj is not None)
        for arr in sub_project:
            plotter_cls(arr, make_plot=(not bool(share) and make_plot),
                        draw=False, ax=next(axes), clear=clear,
                        project=self, enable_post=enable_post, **fmt)
        if share:
            if share is True:
                share = possible_fmts
            elif isinstance(share, six.string_types):
                share = [share]
            else:
                share = list(share)
            sub_project[0].psy.plotter.share(
                [arr.psy.plotter for arr in sub_project[1:]], keys=share,
                draw=False)
            if make_plot:
                for arr in sub_project:
                    arr.psy.plotter.reinit(draw=False, clear=clear)
        if draw is None:
            draw = rcParams['auto_draw']
        if draw:
            sub_project.draw()
            if rcParams['auto_show']:
                self.show()
        self.extend(sub_project, new_name=True)
        if self is gcp(True):
            scp(sub_project)
        return sub_project
Extract data from a dataset and visualize it with the given plotter

        Parameters
        ----------
        plotter_cls: type
            The subclass of :class:`psyplot.plotter.Plotter` to use for
            visualization
        filename_or_obj: filename, :class:`xarray.Dataset` or data store
            The object (or file name) to open. If not a dataset, the
            :func:`psyplot.data.open_dataset` will be used to open a dataset
        fmt: dict
            Formatoptions that shall be when initializing the plot (you can
            however also specify them as extra keyword arguments)
        make_plot: bool
            If True, the data is plotted at the end. Otherwise you have to
            call the :meth:`psyplot.plotter.Plotter.initialize_plot` method or
            the :meth:`psyplot.plotter.Plotter.reinit` method by yourself
        %(InteractiveBase.start_update.parameters.draw)s
        mf_mode: bool
            If True, the :func:`psyplot.open_mfdataset` method is used.
            Otherwise we use the :func:`psyplot.open_dataset` method which can
            open only one single dataset
        ax: None, tuple (x, y[, z]) or (list of) matplotlib.axes.Axes
            Specifies the subplots on which to plot the new data objects.

            - If None, a new figure will be created for each created plotter
            - If tuple (x, y[, z]), `x` specifies the number of rows, `y` the
              number of columns and the optional third parameter `z` the
              maximal number of subplots per figure.
            - If :class:`matplotlib.axes.Axes` (or list of those, e.g. created
              by the :func:`matplotlib.pyplot.subplots` function), the data
              will be plotted on these subplots
        %(open_dataset.parameters.engine)s
        %(multiple_subplots.parameters.delete)s
        share: bool, fmt key or list of fmt keys
            Determines whether the first created plotter shares it's
            formatoptions with the others. If True, all formatoptions are
            shared. Strings or list of strings specify the keys to share.
        clear: bool
            If True, axes are cleared before making the plot. This is only
            necessary if the `ax` keyword consists of subplots with projection
            that differs from the one that is needed
        enable_post: bool
            If True, the :attr:`~psyplot.plotter.Plotter.post` formatoption is
            enabled and post processing scripts are allowed. If ``None``, this
            parameter is set to True if there is a value given for the `post`
            formatoption in `fmt` or `kwargs`
        %(xarray.open_mfdataset.parameters.concat_dim)s
            This parameter only does have an effect if `mf_mode` is True.
        load: bool
            If True, load the complete dataset into memory before plotting.
            This might be useful if the data of other variables in the dataset
            has to be accessed multiple times, e.g. for unstructured grids.
        %(ArrayList.from_dataset.parameters.no_base)s

        Other Parameters
        ----------------
        %(ArrayList.from_dataset.other_parameters.no_args_kwargs)s
        ``**kwargs``
            Any other dimension or formatoption that shall be passed to `dims`
            or `fmt` respectively.

        Returns
        -------
        Project
            The subproject that contains the new (visualized) data array