[yt-svn] commit/yt: 2 new changesets

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Wed Apr 2 14:45:25 PDT 2014


2 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/711de4585e0f/
Changeset:   711de4585e0f
Branch:      yt-3.0
User:        MatthewTurk
Date:        2014-04-02 16:49:24
Summary:     Removing PlotCollection as per YTEP-0020.
Affected #:  11 files

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 doc/coding_styleguide.txt
--- a/doc/coding_styleguide.txt
+++ b/doc/coding_styleguide.txt
@@ -34,11 +34,11 @@
  * Do not import "*" from anything other than "yt.funcs".
  * Internally, only import from source files directly -- instead of:
 
-   from yt.visualization.api import PlotCollection
+   from yt.visualization.api import ProjectionPlot
 
    do:
 
-   from yt.visualization.plot_collection import PlotCollection
+   from yt.visualization.plot_window import ProjectionPlot
 
  * Numpy is to be imported as "np", after a long time of using "na".
  * Do not use too many keyword arguments.  If you have a lot of keyword

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 doc/docstring_idioms.txt
--- a/doc/docstring_idioms.txt
+++ b/doc/docstring_idioms.txt
@@ -43,7 +43,7 @@
 To indicate the return type of a given object, you can reference it using this
 construction:
 
-    This function returns a :class:`PlotCollection`.
+    This function returns a :class:`ProjectionPlot`.
 
 To reference a function, you can use:
 
@@ -51,4 +51,4 @@
 
 To reference a method, you can use:
 
-    To add a projection, use :meth:`PlotCollection.add_projection`.
+    To add a projection, use :meth:`ProjectionPlot.set_width`.

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -15,18 +15,6 @@
    ~yt.visualization.plot_window.ProjectionPlot
    ~yt.visualization.plot_window.OffAxisProjectionPlot
 
-PlotCollection
-^^^^^^^^^^^^^^
-
-.. autosummary::
-   :toctree: generated/
-
-   ~yt.visualization.plot_collection.PlotCollection
-   ~yt.visualization.plot_collection.PlotCollectionInteractive
-   ~yt.visualization.fixed_resolution.FixedResolutionBuffer
-   ~yt.visualization.fixed_resolution.ObliqueFixedResolutionBuffer
-   ~yt.visualization.base_plot_types.get_multi_plot
-
 Data Sources
 ------------
 

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/__init__.py
--- a/yt/__init__.py
+++ b/yt/__init__.py
@@ -137,8 +137,7 @@
 
 # Now individual component imports from the visualization API
 from yt.visualization.api import \
-    PlotCollection, PlotCollectionInteractive, \
-    get_multi_plot, FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
+    FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
     write_bitmap, write_image, \
     apply_colormap, scale_image, write_projection, \
     SlicePlot, AxisAlignedSlicePlot, OffAxisSlicePlot, \

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/frontends/enzo/simulation_handling.py
--- a/yt/frontends/enzo/simulation_handling.py
+++ b/yt/frontends/enzo/simulation_handling.py
@@ -201,9 +201,8 @@
 
         >>> # after calling get_time_series
         >>> for pf in es.piter():
-        ...     pc = PlotCollection(pf, 'c')
-        ...     pc.add_projection('Density', 0)
-        ...     pc.save()
+        ...     p = ProjectionPlot(pf, 'x', "density")
+        ...     p.save()
 
         >>> # An example using the setup_function keyword
         >>> def print_time(pf):

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -1152,17 +1152,15 @@
 
     def __call__(self, args):
         pf = args.pf
-        pc=PlotCollection(pf, center=0.5*(pf.domain_left_edge +
-                                          pf.domain_right_edge))
         if args.axis == 4:
             print "Doesn't work with multiple axes!"
             return
         if args.projection:
-            p = pc.add_projection(args.field, args.axis, weight_field=args.weight)
+            p = ProjectionPlot(pf, args.axis, args.field, weight_field=args.weight)
         else:
-            p = pc.add_slice(args.field, args.axis)
+            p = SlicePlot(pf, args.axis, args.field)
         from yt.gui.reason.pannable_map import PannableMapServer
-        mapper = PannableMapServer(p.data, args.field)
+        mapper = PannableMapServer(p.data_source, args.field)
         import yt.extern.bottle as bottle
         bottle.debug(True)
         if args.host is not None:

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/utilities/minimal_representation.py
--- a/yt/utilities/minimal_representation.py
+++ b/yt/utilities/minimal_representation.py
@@ -227,3 +227,15 @@
         metadata = self._attrs
         chunks = [ ("notebook", self.data) ]
         return (metadata, ("chunks", chunks))
+
+class ImageCollection(object):
+    def __init__(self, pf, name):
+        self.pf = pf
+        self.name = name
+        self.images = []
+        self.image_metadata = []
+
+    def add_image(self, fn, descr):
+        self.image_metadata.append(descr)
+        self.images.append((os.path.basename(fn), np.fromfile(fn, dtype='c')))
+

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -17,11 +17,6 @@
     add_cmap, \
     show_colormaps
 
-from plot_collection import \
-    PlotCollection, \
-    PlotCollectionInteractive, \
-    concatenate_pdfs
-
 from fixed_resolution import \
     FixedResolutionBuffer, \
     ObliqueFixedResolutionBuffer

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/visualization/eps_writer.py
--- a/yt/visualization/eps_writer.py
+++ b/yt/visualization/eps_writer.py
@@ -23,10 +23,6 @@
     y_dict, y_names, \
     axis_names, \
     axis_labels
-from .plot_types import \
-    VMPlot, \
-    ProfilePlot
-from .plot_collection import PlotCollection
 from .plot_window import PlotWindow
 from .profile_plotter import PhasePlot
 from .plot_modifications import get_smallest_appropriate_unit
@@ -289,13 +285,9 @@
             plot.refresh()
         else:
             plot._redraw_image()
-        if isinstance(plot, (VMPlot, PlotWindow)):
-            if isinstance(plot, PlotWindow):
-                data = plot._frb
-                width = plot.width[0]
-            else:
-                data = plot.data
-                width = plot.width
+        if isinstance(plot, PlotWindow):
+            data = plot._frb
+            width = plot.width[0]
             if units == None:
                 units = get_smallest_appropriate_unit(width, plot.pf)
             _xrange = (0, width * plot.pf[units])
@@ -455,11 +447,6 @@
             # hack to account for non-square display ratios (not sure why)
             if isinstance(plot, PlotWindow):
                 shift = 12.0 / 340
-        elif isinstance(plot, ProfilePlot):
-            plot._redraw_image()
-            # Remove colorbar
-            _p1 = plot._figure
-            _p1.delaxes(_p1.axes[1])
         else:
             raise RuntimeError("Unknown plot type")
 

diff -r 6b95f2a269c34bcbdff3ca212b67ddce1401d9e9 -r 711de4585e0f11b3a0b51b39c00faf769136a064 yt/visualization/plot_collection.py
--- a/yt/visualization/plot_collection.py
+++ /dev/null
@@ -1,1679 +0,0 @@
-""" 
-All of the base-level stuff for plotting.
-
-
-
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (c) 2013, yt Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-#-----------------------------------------------------------------------------
-
-from matplotlib import figure
-import shutil
-import tempfile
-import numpy as np
-import os
-
-from yt.funcs import *
-
-from yt.config import ytcfg
-from yt.data_objects.profiles import \
-    BinnedProfile1D, \
-    BinnedProfile2D
-from yt.utilities.definitions import \
-    axis_names, inv_axis_names, x_dict, y_dict
-from .plot_types import \
-    FixedResolutionPlot, \
-    PCSlicePlot, \
-    PCSlicePlotNaturalNeighbor, \
-    PCProjectionPlot, \
-    PCProjectionPlotNaturalNeighbor, \
-    CuttingPlanePlot, \
-    ParticlePlot, \
-    ProfilePlot, \
-    Profile1DPlot, \
-    PhasePlot, \
-    LineQueryPlot, \
-    ScatterPlot
-from yt.utilities.minimal_representation import \
-    MinimalImageCollectionData
-
-# No better place to put this
-def concatenate_pdfs(output_fn, input_fns):
-    from pyPdf import PdfFileWriter, PdfFileReader
-    outfile = PdfFileWriter()
-    for fn in input_fns:
-        infile = PdfFileReader(open(fn, 'rb'))
-        outfile.addPage(infile.getPage(0))
-    outfile.write(open(output_fn, "wb"))
-
-class ImageCollection(object):
-    def __init__(self, pf, name):
-        self.pf = pf
-        self.name = name
-        self.images = []
-        self.image_metadata = []
-
-    def add_image(self, fn, descr):
-        self.image_metadata.append(descr)
-        self.images.append((os.path.basename(fn), np.fromfile(fn, dtype='c')))
-
-class PlotCollection(object):
-    r"""The PlotCollection object was created to ease the creation of multiple
-    slices, projections and so forth made from a single parameter file.
-    The concept is that when the width on one image changes, it should
-    change on all the others.  The PlotCollection can create all plot types
-    available in yt.
-
-    Parameters
-    ----------
-    pf : `Dataset`
-        The parameter file from which all the plots will be created.
-    center : array_like, optional
-        The 'center' supplied to plots like sphere plots, slices, and so
-        on.  Should be 3 elements.  Defaults to the point of maximum
-        density.
-    Long_variable_name : {'hi', 'ho'}, optional
-        Choices in brackets, default first when optional.
-
-    Notes
-    -----
-    This class is the primary entry point to creating plots, but it is not
-    the only entry point.  Additionally, creating a PlotCollection should
-    be a "cheap" operation.
-
-    You may iterate over the plots in the PlotCollection, via something
-    like:
-
-    >>> pc = PlotCollection(pf)
-    >>> for p in pc: print p
-
-    Examples
-    --------
-
-    >>> pc = PlotCollection(pf, center=[0.5, 0.5, 0.5])
-    >>> pc.add_slice("Density", 'x')
-    >>> pc.save()
-
-    """
-
-    __id_counter = 0
-    def __init__(self, pf, center=None):
-        self.plots = []
-        self.pf = pf
-        if center == None:
-            v,self.c = pf.h.find_max("Density") # @todo: ensure no caching
-        elif center == "center" or center == "c":
-            self.c = (pf.domain_right_edge + pf.domain_left_edge)/2.0
-        else:
-            self.c = np.array(center, dtype='float64')
-        mylog.info("Created plot collection with default plot-center = %s",
-                    list(self.c))
-
-    def __iter__(self):
-        for p in self.plots:
-            yield p
-
-    @property
-    def _mrep(self):
-        ic = ImageCollection(self.pf, "Plot Collection with center %s" % self.c)
-        dd = tempfile.mkdtemp()
-        fns = self.save(os.path.join(dd, "temp"))
-        for fn, p in zip(fns, self.plots):
-            ic.add_image(fn, p._pretty_name())
-        shutil.rmtree(dd)
-        return MinimalImageCollectionData(ic)
-
-    def hub_upload(self):
-        self._mrep.upload()
-
-    def save(self, basename=None, format="png", override=False, force_save=False):
-        r"""Save out all the plots hanging off this plot collection, using
-        generated names.
-
-        This function will create names for every plot that belongs to the
-        PlotCollection and save them out.  The names will, by default, be
-        prefixed with the name of the affiliate parameter file, and the file
-        names should indicate clearly what each plot represents.
-
-        Parameters
-        ----------
-        basename : string, optional
-            The prefix for all of the plot filenames.
-        format : string, optional
-            The plot file format.  Can be 'png', 'pdf', 'eps', 'jpg', or
-            anything else that matplotlib understands.
-        override : boolean
-            If this is true, then no generated filenames will be appended to
-            the base name.  You probably don't want this.
-        force_save : boolean
-            In parallel, only the root task (proc 0) saves an image, unless
-            this is set to True.
-
-        Returns
-        -------
-        items : string
-            This function returns a list of the filenames created.
-
-        Examples
-        --------
-
-        >>> fns = pc.save()
-        >>> for fn in fns: print "Saved", fn
-        """
-        if basename is None: basename = str(self.pf)
-        fn = []
-        for plot in self.plots:
-            fn.append(plot.save_image(basename, format=format, 
-                      override=override, force_save=force_save))
-            mylog.info("Saved %s", fn[-1])
-        if ytcfg.getboolean("yt", "__withinreason"):
-            from yt.gui.reason.bottle_mods import PayloadHandler
-            import base64
-            ph = PayloadHandler()
-            for f in fn:
-                if not f.endswith('png'): continue
-                img_data = base64.b64encode(open(f,'rb').read())
-                payload = {'type':'png_string',
-                           'image_data':img_data}
-                ph.add_payload(payload)
-        return fn
-
-    def set_xlim(self, xmin, xmax):
-        r"""Set the x-limits of all plots.
-
-        set_xlim on all plots is called with the parameters passed to this
-        function.
-
-        Parameters
-        ----------
-        xmin : float
-            The left boundary for the x axis.
-        xmax : float
-            The right boundary for the x axis.
-        """
-        for plot in self.plots:
-            plot.set_xlim(xmin, xmax)
-
-    def set_ylim(self, ymin, ymax):
-        r"""Set the y-limits of all plots.
-
-        set_ylim on all plots is called with the parameters passed to this
-        function.
-
-        Parameters
-        ----------
-        ymin : float
-            The left boundary for the x axis.
-        ymax : float
-            The right boundary for the x axis.
-        """
-        for plot in self.plots:
-            plot.set_ylim(ymin, ymax)
-
-    def set_zlim(self, zmin, zmax, *args, **kwargs):
-        """
-        Set the limits of the colorbar. 'min' or 'max' are possible inputs 
-        when combined with dex=value, where value gives the maximum number of 
-        dex to go above/below the min/max.  If value is larger than the true
-        range of values, min/max are limited to true range.
-
-        Only ONE of the following options can be specified. If all 3 are
-        specified, they will be used in the following precedence order:
-
-        * ``ticks`` - a list of floating point numbers at which to put ticks
-        * ``minmaxtick`` - display DEFAULT ticks with min & max also displayed
-        * ``nticks`` - if ticks not specified, can automatically determine a
-          number of ticks to be evenly spaced in log space
-        """
-        for plot in self.plots:
-            plot.set_autoscale(False)
-            plot.set_zlim(zmin, zmax, *args, **kwargs)
-
-    def set_lim(self, lim):
-        r"""Set the x- and y-limits of all plots.
-
-        set_xlim on all plots is called with the parameters passed to this
-        function, and then set_ylim is called.
-
-        Parameters
-        ----------
-        lim : tuple of floats
-            (xmin, xmax, ymin, ymax)
-        """
-        for plot in self.plots:
-            plot.set_xlim(*lim[:2])
-            plot.set_ylim(*lim[2:])
-
-    def autoscale(self):
-        r"""Turn on autoscaling on all plots.
-
-        This has the same effect as:
-
-        >>> for p in pc: p.set_autoscale(True)
-
-        By default, all plots are autoscaled until the colorbar is set
-        manually.  This turns autoscaling back on.  The colors may not be
-        updated unless _redraw_image is called on the plots, which should occur
-        with a change in the width or saving of images.
-        """
-        for plot in self.plots:
-            plot.set_autoscale(True)
-
-    def set_width(self, width, unit):
-        r"""Change the width of all image plots.
-
-        This function changes all the widths of the image plots (but notably
-        not any phase plots or profile plots) to be a given physical extent.
-
-        Parameters
-        ----------
-        width : float
-            The numeric value of the new width.
-        unit : string
-            The unit in which the given width is expressed.
-        """
-        for plot in self.plots:
-            plot.set_width(width, unit)
-
-    def set_cmap(self, cmap):
-        r"""Change the colormap of all plots.
-
-        This function will update the colormap on all plots for which a
-        colormap makes sense.  The colors may not be updated unless
-        _redraw_image is called on the plots, which should occur with a change
-        in the width or saving of images.
-
-        Parameters
-        ----------
-        cmap : string
-            An acceptable colormap.  See either yt.visualization.color_maps or
-            http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
-        """
-        for plot in self.plots:
-            plot.set_cmap(cmap)
-
-    def switch_field(self, field):
-        r"""Change the displayed of all image plots.
-
-        All images that display a field -- slices, cutting planes, projections
-        -- will be switched to display the specified field.  For projections,
-        this will re-generate the projection, if it is unable to load the
-        projected field off-disk.
-
-        Parameters
-        ----------
-        field : string
-            Any field that can be generated or read from disk.
-        """
-        for plot in self.plots:
-            plot.switch_z(field)
-    switch_z = switch_field
-
-    def _add_plot(self, plot):
-        r"""This function adds a plot to the plot collection.
-
-        This function is typically used internally to add a plot on to the
-        current list of plots.  However, if you choose to manually create a
-        plot, this can be used to add it to a collection for convenient
-        modification.
-
-        Parameters
-        ----------
-        plot : `yt.visualization.plot_types.RavenPlot`
-            A plot, which will be appended to the list of plots handled by this
-            plot collection.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.RavenPlot`
-            The plot handed to the function is passed back through.  This is
-            unnecessary, but is done for historical reasons.
-        """
-        self.plots.append(plot)
-        return plot
-
-    def add_slice(self, field, axis, coord=None, center=None,
-                 use_colorbar=True, figure = None, axes = None, fig_size=None,
-                 periodic = True, obj = None, field_parameters = None):
-        r"""Create a slice, from that a slice plot, and add it to the current
-        collection.
-
-        This function will generate a `yt.data_objects.api.YTSliceBase` from the given
-        parameters.  This slice then gets passed to a `yt.visualization.plot_types.PCSlicePlot`, and
-        the resultant plot is added to the current collection.  Various
-        parameters allow control of the way the slice is displayed, as well as
-        how the slice is generated.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        axis : int
-            The axis along which to slice.  Can be 0, 1, or 2 or x, y, z.
-        coord : float, optional
-            The coordinate to place the slice at, along the slicing axis.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        periodic : boolean, optional
-            By default, the slices are assumed to be periodic, and they will
-            wrap around the edges.
-        obj : `yt.data_objects.api.YTSliceBase`, optional
-            If you would like to use an existing slice, you may specify it
-            here, in which case a new slice will not be created.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PCSlicePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTSliceBase : This is the type created by this function and
-                                passed to the plot created here.
-
-        Notes
-        -----
-        This is the primary mechanism for creating slice plots, and generating
-        slice plots along multiple axes was the original purpose of the
-        PlotCollection.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_slice("Density", 'x')
-        """
-        axis = fix_axis(axis)
-        if center == None:
-            center = self.c
-        if coord == None:
-            coord = center[axis]
-        if obj is None:
-            if field_parameters is None: field_parameters = {}
-            obj = self.pf.index.slice(axis, coord, center=center,
-                            field_parameters = field_parameters)
-        p = self._add_plot(PCSlicePlot(
-                         obj, field, use_colorbar=use_colorbar,
-                         axes=axes, figure=figure,
-                         size=fig_size, periodic=periodic))
-        mylog.info("Added slice of %s at %s = %s with 'center' = %s", field,
-                    axis_names[axis], coord, list(center))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_particles(self, axis, width, p_size=1.0, col='k', stride=1.0,
-                      data_source=None, figure=None, axes=None):
-        r"""Create a plot of a thick slab of particles.
-
-        This function will generate a `yt.data_objects.api.YTRegionBase` from the given
-        parameters, and all particles which are within that region will be
-        plotted.
-
-        Parameters
-        ----------
-        axis : int
-            The axis along which to create the thick slab.  Can be 0, 1, or 2
-            or x, y, z.
-        width : float
-            The width of the thick slab, in code units, from which particles
-            will be plotted.
-        p_size : float, optional
-            The size of the points to be used to represent the particles, in
-            pixels.
-        col : color, optional
-            Specified in matplotlib color specifications, the color that
-            particles should be.
-        stride : float, optional
-            The stride through the particles to plot.  Used to plot every
-            fifth, every tenth, etc.  Note that the sorted order of particles
-            may result in a biased selection of particles.
-        data_source : `yt.data_objects.api.YTDataContainer`, optional
-            If specified, this will be the data source used for obtaining
-            particles.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ParticlePlot`
-            The plot that has been added to the PlotCollection.
-
-        Notes
-        -----
-        This plot type can be very expensive, and does not necessarily produce
-        the best visual results.  Plotting a large number of particles can be
-        very tricky, and often it's much better to instead use a slice or a
-        (thin) projection of deposited density, like particle_density_pyx.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_particles(0, 1.0)
-        """
-        axis = fix_axis(axis)
-        LE = self.pf.domain_left_edge.copy()
-        RE = self.pf.domain_right_edge.copy()
-        LE[axis] = self.c[axis] - width/2.0
-        RE[axis] = self.c[axis] + width/2.0
-        if data_source is None: data_source = self.pf.region(self.c, LE, RE)
-        data_source.axis = axis
-        p = self._add_plot(ParticlePlot(data_source, axis,
-                                        width, p_size, col, stride, figure,
-                                        axes))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_cutting_plane(self, field, normal,
-                          center=None, use_colorbar=True,
-                          figure = None, axes = None, fig_size=None, obj=None,
-                           field_parameters = None):
-        r"""Create a cutting plane, from that a plot, and add it to the current
-        collection.
-
-        A cutting plane is an oblique slice through the simulation volume,
-        oriented by a specified normal vector that is perpendicular to the
-        image plane.  This function will generate a
-        `yt.data_objects.api.YTCuttingPlaneBase` from the given parameters.  This cutting
-        plane then gets passed to a `yt.visualization.plot_types.CuttingPlanePlot`, and the
-        resultant plot is added to the current collection.  Various parameters
-        allow control of the way the slice is displayed, as well as how the
-        plane is generated.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        normal : array_like
-            The vector that defines the desired plane.  For instance, the
-            angular momentum of a sphere.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        obj : `YTCuttingPlaneBase`, optional
-            If you would like to use an existing cutting plane, you may specify
-            it here, in which case a new cutting plane will not be created.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the cutting plane upon
-            creation, which can be used for passing variables to derived
-            fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.CuttingPlanePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTCuttingPlaneBase : This is the type created by this function.
-
-        Notes
-        -----
-        This is the primary mechanism for creating cutting plane plots.  Note
-        that they are somewhat slow, but useful to orient the image in an
-        arbitrary direction.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        Here's a simple mechanism for getting the angular momentum of a
-        collapsing cloud and generating a cutting plane aligned with the
-        angular momentum vector.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> v, c = pf.h.find_max("Density")
-        >>> sp = pf.sphere(c, 1000.0/pf['au'])
-        >>> L = sp.quantities["AngularMomentumVector"]()
-        >>> pc = PlotCollection(pf)
-        >>> p = pc.add_cutting_plane("Density", L)
-        """
-        if center == None:
-            center = self.c
-        if not obj:
-            if field_parameters is None: field_parameters = {}
-            cp = self.pf.index.cutting(normal, center, 
-                    field_parameters = field_parameters)
-        else:
-            cp = obj
-        p = self._add_plot(CuttingPlanePlot(cp, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size))
-        mylog.info("Added plane of %s with 'center' = %s and normal = %s", field,
-                    list(center), list(normal))
-        p["Axis"] = "CuttingPlane"
-        return p
-
-    def add_projection(self, field, axis,  weight_field=None,
-                       data_source = None,
-                       center=None, use_colorbar=True,
-                       figure = None, axes = None, fig_size=None,
-                       periodic = True, obj = None, field_parameters = None):
-        r"""Create a projection, from that a projection plot, and add it to the
-        current collection.
-
-        This function will generate a `yt.data_objects.api.YTOverlapProjBase` from the given
-        parameters.  This projection then gets passed to a
-        `yt.visualization.plot_types.PCProjectionPlot`, and the resultant plot is added to the
-        current collection.  Various parameters allow control of the way the
-        slice is displayed, as well as how the slice is generated.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        axis : int
-            The axis along which to slice.  Can be 0, 1, or 2 or x, y, z.
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This is a data source respecting the `YTDataContainer` protocol (i.e., it
-            has grids and so forth) that will be used as input to the
-            projection.
-        weight_field : string
-            If specified, this will be the weighting field and the resultant
-            projection will be a line-of-sight average, defined as sum( f_i *
-            w_i * dl ) / sum( w_i * dl )
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        periodic : boolean, optional
-            By default, the slices are assumed to be periodic, and they will
-            wrap around the edges.
-        obj : `yt.data_objects.api.YTOverlapProjBase`, optional
-            If you would like to use an existing projection, you may specify it
-            here, in which case a new projection will not be created.  If this
-            option is specified the options data_source, weight_field and
-            field_parameters will be ignored.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PCProjectionPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTOverlapProjBase : This is the type created by this function and
-                               passed to the plot created here.
-
-        Notes
-        -----
-        This is the primary mechanism for creating projection plots, and
-        generating projection plots along multiple axes was the original
-        purpose of the PlotCollection.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_projection("Density", 'x', "Density")
-        """
-        axis = fix_axis(axis)
-        if field_parameters is None: field_parameters = {}
-        if center == None:
-            center = self.c
-        if obj is None:
-            obj = self.pf.index.proj(field, axis, weight_field,
-                                         data_source = data_source, center=center,
-                                         field_parameters = field_parameters)
-        p = self._add_plot(PCProjectionPlot(obj, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size, periodic=periodic))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_thin_projection(self, field, axis, thickness,
-                       weight_field=None, center=None, use_colorbar=True,
-                       figure = None, axes = None, fig_size=None,
-                       periodic = True, field_parameters = None):
-        r"""Create a projection through a thin slice of the domain, from that a
-        projection plot, and add it to the current collection.
-
-        This function will generate a rectangular prism region and supply it to
-        a`yt.data_objects.api.YTOverlapProjBase` from the given parameters.  This projection
-        then gets passed to a `yt.visualization.plot_types.PCProjectionPlot`, and the resultant plot
-        is added to the current collection.  Various parameters allow control
-        of the way the slice is displayed, as well as how the slice is
-        generated.  The center is used as the center of the thin projection.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        axis : int
-            The axis along which to slice.  Can be 0, 1, or 2 or x, y, z.
-        thickness : float
-            In 'code units' this is the thickness of the region to be
-            projected through.
-        weight_field : string
-            If specified, this will be the weighting field and the resultant
-            projection will be a line-of-sight average, defined as sum( f_i *
-            w_i * dl ) / sum( w_i * dl )
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        periodic : boolean, optional
-            By default, the slices are assumed to be periodic, and they will
-            wrap around the edges.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PCProjectionPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTOverlapProjBase : This is the type created by this function and
-                               passed to the plot created here.
-
-        Notes
-        -----
-        This is the primary mechanism for creating projection plots, and
-        generating projection plots along multiple axes was the original
-        purpose of the PlotCollection.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_thin_projection("Density", 0, 0.1, "Density")
-        """
-        axis = fix_axis(axis)
-        if field_parameters is None: field_parameters = {}
-        if center == None:
-            center = self.c
-        LE = self.pf.domain_left_edge.copy()
-        RE = self.pf.domain_right_edge.copy()
-        LE[axis] = RE[axis] = center[axis]
-        LE[axis] -= thickness/2.0
-        RE[axis] += thickness/2.0
-        region = self.pf.region(center, LE, RE)
-        obj = self.pf.index.proj(field, axis, weight_field,
-                                     data_source = region, center=center,
-                                     field_parameters = field_parameters)
-        p = self._add_plot(PCProjectionPlot(obj, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size, periodic=periodic))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_profile_object(self, data_source, fields,
-                           weight="CellMassMsun", accumulation=False,
-                           x_bins=128, x_log=True, x_bounds=None,
-                           id=None, figure=None, axes=None):
-        r"""From an existing object, create a 1D, binned profile.
-
-        This function will accept an existing `YTDataContainer` source and from that,
-        it will generate a `Binned1DProfile`, based on the specified options.
-        This is useful if you have extracted a region, or if you wish to bin
-        some set of massages data -- or even if you wish to bin anything other
-        than a sphere.  The profile will be 1D, which means while it can have
-        an arbitrary number of fields, those fields will all be binned based on
-        a single field.
-
-        Parameters
-        ----------
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This is a data source respecting the `YTDataContainer` protocol (i.e., it
-            has grids and so forth) that will be used as input to the profile
-            generation.
-        fields : list of strings
-            The first element of this list is the field by which we will bin;
-            all subsequent fields will be binned and their profiles added to
-            the underlying `BinnedProfile1D`.
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : boolean, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.
-        x_bins : int, optional
-            How many bins should there be in the independent variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ProfilePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile1D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-
-        Examples
-        --------
-
-        >>> reg = pf.region([0.1, 0.2, 0.3], [0.0, 0.1, 0.2],
-                              [0.2, 0.3, 0.4])
-        >>> pc.add_profile_object(reg, ["Density", "Temperature"])
-        """
-        if x_bounds is None:
-            x_min, x_max = data_source.quantities["Extrema"](
-                            fields[0], non_zero = x_log)[0]
-        else:
-            x_min, x_max = x_bounds
-        profile = BinnedProfile1D(data_source,
-                                  x_bins, fields[0], x_min, x_max, x_log)
-        if len(fields) > 1:
-            profile.add_fields(fields[1:], weight=weight, accumulation=accumulation)
-        if id is None: id = self._get_new_id()
-        p = self._add_plot(Profile1DPlot(profile, fields, id,
-                                                   axes=axes, figure=figure))
-        return p
-
-    def add_profile_sphere(self, radius, unit, fields, center = None,
-                           weight="CellMassMsun", accumulation=False,
-                           x_bins=128, x_log=True, x_bounds=None,
-                           id=None, figure=None, axes=None):
-        r"""From a description of a sphere, create a 1D, binned profile.
-
-        This function will accept the radius of a sphere, and from that it will
-        generate a `Binned1DProfile`, based on the specified options.  The
-        profile will be 1D, which means while it can have an arbitrary number
-        of fields, those fields will all be binned based on a single field.
-
-        All subsequent parameters beyond "unit" will be passed verbatim to
-        add_profile_object.
-
-        Parameters
-        ----------
-        radius : float
-            The radius of the sphere to generate.
-        unit : string
-            The unit in which the given radius is expressed.
-        fields : list of strings
-            The first element of this list is the field by which we will bin;
-            all subsequent fields will be binned and their profiles added to
-            the underlying `BinnedProfile1D`.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : boolean, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.
-        x_bins : int, optional
-            How many bins should there be in the independent variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ProfilePlot`
-            The plot that has been added to the PlotCollection.  Note that the
-            underlying sphere may be accessed as .data.data_source
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile1D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-        yt.data_objects.api.YTSphereBase : This is the object auto-generated by this
-                                 function.
-
-        Examples
-        --------
-
-        >>> pc.add_profile_sphere(1.0, 'kpc', ["Density", "Electron_Fraction"])
-        """
-        if center is None:
-            center = self.c
-        r = radius/self.pf[unit]
-        sphere = self.pf.index.sphere(center, r)
-        p = self.add_profile_object(sphere, fields, weight, accumulation,
-                           x_bins, x_log, x_bounds, id,
-                           figure=figure, axes=axes)
-        p["Width"] = radius
-        p["Unit"] = unit
-        p["Axis"] = None
-        return p
-
-    def add_phase_object(self, data_source, fields, cmap=None,
-                               weight="CellMassMsun", accumulation=False,
-                               x_bins=128, x_log=True, x_bounds=None,
-                               y_bins=128, y_log=True, y_bounds=None,
-                               id=None, axes = None, figure = None,
-                               fractional=False):
-        r"""From an existing object, create a 2D, binned profile.
-
-        This function will accept an existing `YTDataContainer` source and from that,
-        it will generate a `Binned2DProfile`, based on the specified options.
-        This is useful if you have extracted a region, or if you wish to bin
-        some set of massages data -- or even if you wish to bin anything other
-        than a sphere.  The profile will be 2D, which means while it can have
-        an arbitrary number of fields, those fields will all be binned based on
-        two fields.
-
-        Parameters
-        ----------
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This is a data source respecting the `YTDataContainer` protocol (i.e., it
-            has grids and so forth) that will be used as input to the profile
-            generation.
-        fields : list of strings
-            The first element of this list is the field by which we will bin
-            into the x-axis, the second is the field by which we will bin onto
-            the y-axis.  All subsequent fields will be binned and their
-            profiles added to the underlying `BinnedProfile2D`.
-        cmap : string, optional
-            An acceptable colormap.  See either yt.visualization.color_maps or
-            http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : list of booleans, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.  The first value is for the
-            x-axis, the second value for the y-axis.  Note that accumulation
-            will only be along each row or column.
-        x_bins : int, optional
-            How many bins should there be in the x-axis variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        y_bins : int, optional
-            How many bins should there be in the y-axis variable?
-        y_log : boolean, optional
-            Should the bin edges be log-spaced?
-        y_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fractional : boolean
-            If true, the plot will be normalized to the sum of all the binned
-            values.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PlotTypes.PhasePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile2D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-        
-        Examples
-        --------
-        This will show the mass-distribution in the Density-Temperature plane.
-        
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> reg = pf.region([0.1, 0.2, 0.3], [0.0, 0.1, 0.2],
-        ...                   [0.2, 0.3, 0.4])
-        >>> pc.add_phase_object(reg, ["Density", "Temperature", "CellMassMsun"],
-        ...                     weight = None)
-        """
-        if x_bounds is None:
-            x_min, x_max = data_source.quantities["Extrema"](
-                                    fields[0], non_zero = x_log)[0]
-        else:
-            x_min, x_max = x_bounds
-        if y_bounds is None:
-            y_min, y_max = data_source.quantities["Extrema"](
-                                    fields[1], non_zero = y_log)[0]
-        else:
-            y_min, y_max = y_bounds
-        profile = BinnedProfile2D(data_source,
-                                  x_bins, fields[0], x_min, x_max, x_log,
-                                  y_bins, fields[1], y_min, y_max, y_log)
-        # This will add all the fields to the profile object
-        if len(fields)>2:
-            profile.add_fields(fields[2:], weight=weight,
-                    accumulation=accumulation, fractional=fractional)
-
-        if id is None: id = self._get_new_id()
-        p = self._add_plot(PhasePlot(profile, fields, 
-                                               id, cmap=cmap,
-                                               figure=figure, axes=axes))
-        return p
-
-    def add_phase_sphere(self, radius, unit, fields, center = None, cmap=None,
-                         weight="CellMassMsun", accumulation=False,
-                         x_bins=128, x_log=True, x_bounds=None,
-                         y_bins=128, y_log=True, y_bounds=None,
-                         id=None, axes = None, figure = None,
-                         fractional=False):
-        r"""From a description of a sphere, create a 2D, binned profile.
-
-        This function will accept the radius of a sphere, and from that it will
-        generate a `Binned1DProfile`, based on the specified options.  The
-        profile will be 2D, which means while it can have an arbitrary number
-        of fields, those fields will all be binned based on two fields.
-
-        All subsequent parameters beyond "unit" will be passed verbatim to
-        add_profile_object.
-
-        Parameters
-        ----------
-        radius : float
-            The radius of the sphere to generate.
-        unit : string
-            The unit in which the given radius is expressed.
-        fields : list of strings
-            The first element of this list is the field by which we will bin
-            into the y-axis, the second is the field by which we will bin onto
-            the y-axis.  All subsequent fields will be binned and their
-            profiles added to the underlying `BinnedProfile2D`.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        cmap : string, optional
-            An acceptable colormap.  See either yt.visualization.color_maps or
-            http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : list of booleans, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.  The first value is for the
-            x-axis, the second value for the y-axis.  Note that accumulation
-            will only be along each row or column.
-        x_bins : int, optional
-            How many bins should there be in the x-axis variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        y_bins : int, optional
-            How many bins should there be in the y-axis variable?
-        y_log : boolean, optional
-            Should the bin edges be log-spaced?
-        y_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fractional : boolean
-            If true, the plot will be normalized to the sum of all the binned
-            values.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PhasePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile2D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-
-        Examples
-        --------
-
-        This will show the mass-distribution in the Density-Temperature plane.
-
-        >>> pc.add_phase_sphere(1.0, 'kpc',
-                ["Density", "Temperature", "CellMassMsun"], weight = None)
-        """
-
-        if center is None: center = self.c
-        r = radius/self.pf[unit]
-        data_source = self.pf.index.sphere(center, r)
-        p = self.add_phase_object(data_source, fields, cmap,
-                             weight, accumulation,
-                             x_bins, x_log, x_bounds,
-                             y_bins, y_log, y_bounds,
-                             id, axes=axes, figure=figure, fractional=fractional)
-        p["Width"] = radius
-        p["Unit"] = unit
-        p["Axis"] = None
-        return p
-
-    def add_scatter_source(self, data_source, fields, id=None,
-                     figure = None, axes = None, plot_options = None):
-        r"""Given a data source, make a scatter plot from that data source.
-
-        This is a very simple plot: you give it an instance of `YTDataContainer`, two
-        field names, and it will plot them on an axis
-
-        Parameters
-        ----------
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This will be the data source from which field values will be
-            obtained.
-        fields : tuple of strings
-            The first of these will be the x-field, and the second the y-field.
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        plot_options : dict
-            These options will be given to `matplotlib.axes.Axes.scatter`
-        
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ScatterPlot`
-            The plot that has been added to the PlotCollection.
-
-        Notes
-        -----
-        This is a simpler way of making a phase plot, but note that because
-        pixels are deposited in order, the color may be a biased sample.
-
-        Examples
-        --------
-
-        >>> reg = pf.region([0.1, 0.2, 0.3], [0.0, 0.1, 0.2],
-                              [0.2, 0.3, 0.4])
-        >>> pc.add_scatter_plot(reg, ["Density", "Temperature"],
-        >>>                     plot_options = {'color':'b'})
-        """
-        if id is None: id = self._get_new_id()
-        if plot_options is None: plot_options = {}
-        sp = ScatterPlot(data_source, fields, id,
-                                   plot_options = plot_options,
-                                   figure=figure, axes=axes)
-        p = self._add_plot(sp)
-        return p
-
-    def add_fixed_resolution_plot(self, frb, field, use_colorbar=True,
-                      figure = None, axes = None, fig_size=None):
-        r"""Create a fixed resolution image from an existing buffer.
-
-        This accepts a `FixedResolutionBuffer` and will make a plot from that
-        buffer.
-
-        Parameters
-        ----------
-        frb : `yt.visualization.plot_types.FixedResolutionBuffer`
-            The buffer from which fields will be pulled.
-        field : string
-            The initial field to display.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.FixedResolutionPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.extensions.image_writer.write_image : A faster, colorbarless way to
-                                                 write out FRBs.
-
-        Examples
-        --------
-
-        Here's a simple mechanism for getting the angular momentum of a
-        collapsing cloud and generating a cutting plane aligned with the
-        angular momentum vector.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> proj = pf.proj("Density", 0)
-        >>> frb = FixedResolutionBuffer(proj, (0.2, 0.3, 0.4, 0.5), (512, 512))
-        >>> p = pc.add_fixed_resolution_plot(frb, "Density")
-        """
-        p = self._add_plot(FixedResolutionPlot(frb, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size))
-        p["Axis"] = "na"
-        return p
-
-    def add_ortho_ray(self, axis, coords, field, figure = None,
-                      axes = None, field_parameters = None,
-                      plot_options = None):
-        r"""Create a ray parallel to some axis, from that a line plot, and add
-        it to the current collection.
-
-        This function will generate a `yt.data_objects.api.YTOrthoRayBase` from the given
-        parameters.  This ray then gets passed to a `yt.visualization.plot_types.LineQueryPLot`, and
-        the resultant plot is added to the current collection.  Various
-        parameters allow control of the way the line plot is displayed, as well as
-        how the ray is generated.
-
-        Parameters
-        ----------
-        axis : int
-            The axis along which to cast the ray.  Can be 0, 1, or 2 or x, y,
-            z.
-        coords : tuple of floats
-            The coordinates to place the ray at.  Note that the axes are in the
-            form of x_dict[axis] and y_dict[axis] for some axis.
-        field : string
-            The initial field to slice and display.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-        plot_options : dict
-            These options will be given to `matplotlib.axes.Axes.plot`
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.LineQueryPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTOrthoRayBase : This is the type created by this function and
-                                   passed to the plot created here.
-
-        Examples
-        --------
-
-        This will cast a ray from (0.0, 0.5, 0.5) to (1.0, 0.5, 0.5) and plot
-        it.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_ortho_ray(0, (0.5, 0.5), "Density")
-        """
-        axis = fix_axis(axis)
-        if field_parameters is None: field_parameters = {}
-        if plot_options is None: plot_options = {}
-        data_source = self.pf.ortho_ray(axis, coords, 
-                        field_parameters = field_parameters)
-        p = self._add_plot(LineQueryPlot(data_source,
-                [axis_names[axis], field], self._get_new_id(),
-                figure=figure, axes=axes, plot_options=plot_options))
-        return p
-
-    def add_ray(self, start_point, end_point, field, figure = None,
-                axes = None, field_parameters = None, plot_options = None):
-        r"""Create a ray between two points, from that a line plot, and add
-        it to the current collection.
-
-        This function will generate a `yt.data_objects.api.YTRayBase` from the given
-        parameters.  This ray then gets passed to a `yt.visualization.plot_types.LineQueryPLot`, and
-        the resultant plot is added to the current collection.  Various
-        parameters allow control of the way the line plot is displayed, as well as
-        how the ray is generated.
-
-        Parameters
-        ----------
-        start_point : array_like
-            The starting point of the ray.
-        end_point : array_like
-            The ending point of the ray.
-        field : string
-            The initial field to slice and display.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-        plot_options : dict
-            These options will be given to `matplotlib.axes.Axes.plot`
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.LineQueryPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTRayBase : This is the type created by this function and
-                              passed to the plot created here.
-
-        Examples
-        --------
-
-        This will cast a ray from (0.1, 0.2, 0.3) to (0.9, 0.7, 0.4) and plot
-        it.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_ray((0.1, 0.2, 0.3), (0.9, 0.7, 0.4), "Density")
-        """
-        if field_parameters is None: field_parameters = {}
-        if plot_options is None: plot_options = {}
-        data_source = self.pf.ray(start_point, end_point, 
-                                    field_parameters = field_parameters)
-        p = self._add_plot(LineQueryPlot(data_source,
-                ['t', field], self._get_new_id(),
-                figure=figure, axes=axes, plot_options=plot_options))
-        return p
-
-    def _get_new_id(self):
-        self.__id_counter += 1
-        return self.__id_counter-1
-
-    @rootonly
-    def save_book(self, filename, author = None, title = None, keywords = None,
-                  subject = None, creator = None, producer = None,
-                  creation_date = None):
-        r"""Save a multipage PDF of all the current plots, rather than
-        individual image files.
-
-        This function will utilize the matplotlib PDF backend to create a new
-        PDF, and for every plot that the PlotCollection currently has, it will
-        render a new page into that PDF.  The pages will be in the order of the
-        current plots.
-
-        Parameters
-        ----------
-        filename : string
-            The name of the PDF file to generate.  Note that it will be
-            overwritten, and '.pdf' will not be appended.
-        author : string, optional
-            The string to place in the metadata value of the PDF for 'author'.
-        title : string, optional
-            The string to place in the metadata value of the PDF for 'title'.
-        keywords : string, optional
-            The string to place in the metadata value of the PDF for 'keywords'.
-        subject : string, optional
-            The string to place in the metadata value of the PDF for 'subject'.
-        creator : string, optional
-            The string to place in the metadata value of the PDF for 'creator'.
-        producer : string, optional
-            The string to place in the metadata value of the PDF for 'producer'.
-        creation_date : string, optional
-            The string to place in the metadata value of the PDF for
-            'creation_date'.
-
-        Returns
-        -------
-        Nothing
-
-        Examples
-        --------
-        This will set up a new PlotCollection, add some plots, and then save it
-        as a PDF.
-
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> pc.add_projection("Density", 'x')
-        >>> pc.add_projection("Density", 'y')
-        >>> pc.add_projection("Density", 'z')
-        >>> pc.set_width(0.5, 'pc')
-        >>> dd = pf.h.all_data()
-        >>> pc.add_phase_object(dd, ["Density", "Temperature", "CellMassMsun"],
-        ...                     weight = None)
-        >>> pc.save_book("my_plots.pdf", author="Yours Truly",
-        ...              title="Fun plots")
-        """
-        from matplotlib.backends.backend_pdf import PdfPages
-        outfile = PdfPages(filename)
-        for plot in self.plots:
-            plot.save_to_pdf(outfile)
-        pdf_keys = ['Title', 'Author', 'Subject', 'Keywords', 'Creator',
-            'Producer', 'CreationDate']
-        pdf_values = [title, author, subject, keywords, creator, producer,
-            creation_date]
-        metadata = outfile.infodict()
-        for key, val in zip(pdf_keys, pdf_values):
-            if isinstance(val, str):
-                metadata[key] = val
-        outfile.close()
-
-def wrap_pylab_newplot(func):
-    @wraps(func)
-    def pylabify(self, *args, **kwargs):
-        # Let's assume that axes and figure are not in the positional
-        # arguments -- probably safe!
-        new_fig = self.pylab.figure()
-        try:
-            new_fig.canvas.set_window_title("%s" % (self.pf))
-        except AttributeError:
-            pass
-        if 'axes' not in kwargs: kwargs['axes'] = self.pylab.gca()
-        if 'figure' not in kwargs: kwargs['figure'] = self.pylab.gcf()
-        retval = func(self, *args, **kwargs)
-        retval._redraw_image()
-        retval._fig_num = new_fig.number
-        self.pylab.draw()
-        return retval
-    return pylabify
-
-def wrap_pylab_show(func):
-    @wraps(func)
-    def pylabify(self, *args, **kwargs):
-        retval = func(self, *args, **kwargs)
-        fig_num = self.pylab.gcf().number
-        for p in self.plots:
-            self.pylab.figure(p._fig_num)
-            self.pylab.draw()
-        self.pylab.figure(fig_num)
-        return retval
-    return pylabify
-
-class _Interactify(type):
-    # All inherited methods get wrapped if they start with add_ or set_
-    # So anything inheriting this automatically gets set up; additional
-    # wrappings can be done manually.  Note that this does NOT modify
-    # methods that are only in the subclasses.
-    def __init__(cls, name, bases, d):
-        super(_Interactify, cls).__init__(name, bases, d)
-        for base in bases:
-            for attrname in dir(base):
-                if attrname in d: continue # If overridden, don't reset
-                attr = getattr(cls, attrname)
-                if type(attr) == types.MethodType:
-                    if attrname.startswith("add_"):
-                        setattr(cls, attrname, wrap_pylab_newplot(attr))
-                    elif attrname.startswith("set_"):
-                        setattr(cls, attrname, wrap_pylab_show(attr))
-
-class PlotCollectionInteractive(PlotCollection):
-    __metaclass__ = _Interactify
-
-    autoscale = wrap_pylab_show(PlotCollection.autoscale)
-    switch_field = wrap_pylab_show(PlotCollection.switch_field)
-
-    def __init__(self, *args, **kwargs):
-        import pylab
-        self.pylab = pylab
-        super(PlotCollectionInteractive, self).__init__(*args, **kwargs)
-
-    def redraw(self):
-        r"""Redraw all affiliated plots.
-
-        To ensure that any interactive windows are up to date, this function
-        can be called to redraw all images into them.
-        """
-        for plot in self.plots:
-            plot._redraw_image()
-        self.pylab.draw()
-
-    def clear_figures(self):
-        r"""Clear all interactive figures affiliated with this collection.
-
-        Because reusing figures between plot collections can be tricky,
-        occasionally they must be manually cleared to re-obtain empty figures
-        for future plotting.  This will clear all figures.
-        """
-        for plot in self.plots:
-            self.pylab.figure(plot._fig_num)
-            self.pylab.clf()
-
-    def interactive_zoom(self):
-        r"""Enter an interactive zooming session for all plots.
-
-        Use this to enter an interactive session where zoom factors
-        can be entered that are used to set the widths of the plot
-        collection.  This function has no arguments, but will return
-        the final width upon exit.
-
-        Caution: Tested and works with TkAgg and MacOSX backends.  Threaded
-        backends like Qt4Agg are likely to fail.
-
-        Controls:
-        Any numeric value: Zooms by this factor
-        0: Exit interactive zoom session
-        -1: Reset to width of 1.0 in code units
-        empty: zooms by previously entered factor.
-
-        Returns:
-        width: (float) The final width of the plot collection
-        """
-        print 'Enter Zoom Factor, 0 to exit, -1 to reset to width=1.0'
-        zfactor = 1.0
-        while(True):
-            new_zoom = raw_input('zoom:')
-            if new_zoom is not '':
-                try:
-                    zfactor = float(new_zoom)
-                except:
-                    print 'Please enter a valid number, or 0 to exit'
-                    continue
-            else:
-                print 'Using previous zoom value of %e' % zfactor
-            if zfactor == 0.0:
-                break
-            elif zfactor == -1.0:
-                self.set_width(1.0,'1')
-            else:
-                self.set_width(self.plots[0].__dict__['width']/zfactor,'1')
-        print 'Returning final width of %e' % self.plots[0].width
-        return self.plots[0].width
-
-class PlotCollectionIPython(PlotCollection):
-    def save(self, basename = None):
-        r"""Shows all the plots hanging off this plot collection in the IPython
-        web notebook.
-
-        This function will instruct the IPython web notebook to show its
-        images.
-
-        Examples
-        --------
-
-        >>> pc.save()
-        """
-        from ._mpl_imports import FigureCanvasAgg
-        from IPython.zmq.pylab.backend_inline import \
-            send_figure
-        if basename is None: basename = str(self.pf)
-        for plot in self.plots:
-            canvas = FigureCanvasAgg(plot._figure)
-            send_figure(plot._figure)
-
-def _MPLFixImage(data_source, image_obj, field, cbar, cls):
-    nx, ny = image_obj.get_size()
-    def f(axes):
-        x0, x1 = axes.get_xlim()
-        y0, y1 = axes.get_ylim()
-        frb = cls(data_source, (x0, x1, y0, y1), (nx, ny))
-        image_obj.set_data(frb[field])
-        mi, ma = frb[field].min(), frb[field].max()
-        cbar.norm.autoscale((mi, ma))
-        image_obj.set_extent([x0, x1, y0, y1])
-        cbar.update_bruteforce(image_obj)
-    return f
-
-def matplotlib_widget(data_source, field, npix):
-    r"""Create a widget from a data_source that uses the Matplotlib interaction
-    method to pan, zoom, and so on.
-
-    This is a simple way to take a yt data source, for instance a projection or
-    a slice, and to create a matplotlib view into it that you can pan and zoom.
-    It uses the matplotlib interaction engine to manage input and display.
-
-    Parameters
-    ----------
-    data_source : :class:`yt.data_objects.data_containers.YTOverlapProjBase` or :class:`yt.data_objects.data_containers.YTSliceBase`
-        This is the source to be pixelized, which can be a projection or a
-        slice.  
-    field : string
-        The field that you want to display in the window.
-    npix : int
-        The number of pixels on a side you want the image to be.
-
-    Examples
-    --------
-
-    >>> pf = load("DD0030/DD0030")
-    >>> p = pf.proj("Density", "z")
-    >>> matplotlib_widget(p, "Density", 1024)
-
-    """
-    import pylab
-    import matplotlib.colors
-    from .fixed_resolution import FixedResolutionBuffer, \
-            ObliqueFixedResolutionBuffer
-    pf = data_source.pf
-    if getattr(data_source, "axis", 4) < 3:
-        cls = FixedResolutionBuffer
-        ax = data_source.axis
-        extent = [pf.domain_left_edge[x_dict[ax]],
-                  pf.domain_right_edge[x_dict[ax]],
-                  pf.domain_left_edge[y_dict[ax]],
-                  pf.domain_right_edge[y_dict[ax]]]
-    else:
-        cls = ObliqueFixedResolutionBuffer
-        extent = [0.0, 1.0, 0.0, 1.0]
-    take_log = pf.field_info[field].take_log
-    if take_log:
-        norm = matplotlib.colors.LogNorm()
-    else:
-        norm = matplotlib.colors.Normalize()
-    ax = pylab.figure().gca()
-    ax.autoscale(False)
-    axi = ax.imshow(np.random.random((npix, npix)),
-                    extent = extent, norm = norm,
-                    origin = 'lower')
-    cb = pylab.colorbar(axi, norm = norm)
-    showme = _MPLFixImage(data_source, axi, field, cb, cls)
-    ax.callbacks.connect("xlim_changed", showme)
-    ax.callbacks.connect("ylim_changed", showme)
-    ax.set_xlim(extent[0], extent[1])
-    ax.set_ylim(extent[2], extent[3])
-    return ax

This diff is so big that we needed to truncate the remainder.

https://bitbucket.org/yt_analysis/yt/commits/be0b501dbc67/
Changeset:   be0b501dbc67
Branch:      yt-3.0
User:        ngoldbaum
Date:        2014-04-02 23:45:18
Summary:     Merged in MatthewTurk/yt/yt-3.0 (pull request #785)

Removing PlotCollection as per YTEP-0020.
Affected #:  11 files

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf doc/coding_styleguide.txt
--- a/doc/coding_styleguide.txt
+++ b/doc/coding_styleguide.txt
@@ -34,11 +34,11 @@
  * Do not import "*" from anything other than "yt.funcs".
  * Internally, only import from source files directly -- instead of:
 
-   from yt.visualization.api import PlotCollection
+   from yt.visualization.api import ProjectionPlot
 
    do:
 
-   from yt.visualization.plot_collection import PlotCollection
+   from yt.visualization.plot_window import ProjectionPlot
 
  * Numpy is to be imported as "np", after a long time of using "na".
  * Do not use too many keyword arguments.  If you have a lot of keyword

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf doc/docstring_idioms.txt
--- a/doc/docstring_idioms.txt
+++ b/doc/docstring_idioms.txt
@@ -43,7 +43,7 @@
 To indicate the return type of a given object, you can reference it using this
 construction:
 
-    This function returns a :class:`PlotCollection`.
+    This function returns a :class:`ProjectionPlot`.
 
 To reference a function, you can use:
 
@@ -51,4 +51,4 @@
 
 To reference a method, you can use:
 
-    To add a projection, use :meth:`PlotCollection.add_projection`.
+    To add a projection, use :meth:`ProjectionPlot.set_width`.

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -15,18 +15,6 @@
    ~yt.visualization.plot_window.ProjectionPlot
    ~yt.visualization.plot_window.OffAxisProjectionPlot
 
-PlotCollection
-^^^^^^^^^^^^^^
-
-.. autosummary::
-   :toctree: generated/
-
-   ~yt.visualization.plot_collection.PlotCollection
-   ~yt.visualization.plot_collection.PlotCollectionInteractive
-   ~yt.visualization.fixed_resolution.FixedResolutionBuffer
-   ~yt.visualization.fixed_resolution.ObliqueFixedResolutionBuffer
-   ~yt.visualization.base_plot_types.get_multi_plot
-
 Data Sources
 ------------
 

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/__init__.py
--- a/yt/__init__.py
+++ b/yt/__init__.py
@@ -137,8 +137,7 @@
 
 # Now individual component imports from the visualization API
 from yt.visualization.api import \
-    PlotCollection, PlotCollectionInteractive, \
-    get_multi_plot, FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
+    FixedResolutionBuffer, ObliqueFixedResolutionBuffer, \
     write_bitmap, write_image, \
     apply_colormap, scale_image, write_projection, \
     SlicePlot, AxisAlignedSlicePlot, OffAxisSlicePlot, \

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/frontends/enzo/simulation_handling.py
--- a/yt/frontends/enzo/simulation_handling.py
+++ b/yt/frontends/enzo/simulation_handling.py
@@ -201,9 +201,8 @@
 
         >>> # after calling get_time_series
         >>> for pf in es.piter():
-        ...     pc = PlotCollection(pf, 'c')
-        ...     pc.add_projection('Density', 0)
-        ...     pc.save()
+        ...     p = ProjectionPlot(pf, 'x', "density")
+        ...     p.save()
 
         >>> # An example using the setup_function keyword
         >>> def print_time(pf):

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/utilities/command_line.py
--- a/yt/utilities/command_line.py
+++ b/yt/utilities/command_line.py
@@ -1152,17 +1152,15 @@
 
     def __call__(self, args):
         pf = args.pf
-        pc=PlotCollection(pf, center=0.5*(pf.domain_left_edge +
-                                          pf.domain_right_edge))
         if args.axis == 4:
             print "Doesn't work with multiple axes!"
             return
         if args.projection:
-            p = pc.add_projection(args.field, args.axis, weight_field=args.weight)
+            p = ProjectionPlot(pf, args.axis, args.field, weight_field=args.weight)
         else:
-            p = pc.add_slice(args.field, args.axis)
+            p = SlicePlot(pf, args.axis, args.field)
         from yt.gui.reason.pannable_map import PannableMapServer
-        mapper = PannableMapServer(p.data, args.field)
+        mapper = PannableMapServer(p.data_source, args.field)
         import yt.extern.bottle as bottle
         bottle.debug(True)
         if args.host is not None:

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/utilities/minimal_representation.py
--- a/yt/utilities/minimal_representation.py
+++ b/yt/utilities/minimal_representation.py
@@ -227,3 +227,15 @@
         metadata = self._attrs
         chunks = [ ("notebook", self.data) ]
         return (metadata, ("chunks", chunks))
+
+class ImageCollection(object):
+    def __init__(self, pf, name):
+        self.pf = pf
+        self.name = name
+        self.images = []
+        self.image_metadata = []
+
+    def add_image(self, fn, descr):
+        self.image_metadata.append(descr)
+        self.images.append((os.path.basename(fn), np.fromfile(fn, dtype='c')))
+

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/visualization/api.py
--- a/yt/visualization/api.py
+++ b/yt/visualization/api.py
@@ -17,11 +17,6 @@
     add_cmap, \
     show_colormaps
 
-from plot_collection import \
-    PlotCollection, \
-    PlotCollectionInteractive, \
-    concatenate_pdfs
-
 from fixed_resolution import \
     FixedResolutionBuffer, \
     ObliqueFixedResolutionBuffer

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/visualization/eps_writer.py
--- a/yt/visualization/eps_writer.py
+++ b/yt/visualization/eps_writer.py
@@ -23,10 +23,6 @@
     y_dict, y_names, \
     axis_names, \
     axis_labels
-from .plot_types import \
-    VMPlot, \
-    ProfilePlot
-from .plot_collection import PlotCollection
 from .plot_window import PlotWindow
 from .profile_plotter import PhasePlot
 from .plot_modifications import get_smallest_appropriate_unit
@@ -289,13 +285,9 @@
             plot.refresh()
         else:
             plot._redraw_image()
-        if isinstance(plot, (VMPlot, PlotWindow)):
-            if isinstance(plot, PlotWindow):
-                data = plot._frb
-                width = plot.width[0]
-            else:
-                data = plot.data
-                width = plot.width
+        if isinstance(plot, PlotWindow):
+            data = plot._frb
+            width = plot.width[0]
             if units == None:
                 units = get_smallest_appropriate_unit(width, plot.pf)
             _xrange = (0, width * plot.pf[units])
@@ -455,11 +447,6 @@
             # hack to account for non-square display ratios (not sure why)
             if isinstance(plot, PlotWindow):
                 shift = 12.0 / 340
-        elif isinstance(plot, ProfilePlot):
-            plot._redraw_image()
-            # Remove colorbar
-            _p1 = plot._figure
-            _p1.delaxes(_p1.axes[1])
         else:
             raise RuntimeError("Unknown plot type")
 

diff -r 9d801c404e78bbe31d7680e6e5cb3a9d03da6c7d -r be0b501dbc67e4feb9f960250a3a5b75071b62bf yt/visualization/plot_collection.py
--- a/yt/visualization/plot_collection.py
+++ /dev/null
@@ -1,1679 +0,0 @@
-""" 
-All of the base-level stuff for plotting.
-
-
-
-"""
-
-#-----------------------------------------------------------------------------
-# Copyright (c) 2013, yt Development Team.
-#
-# Distributed under the terms of the Modified BSD License.
-#
-# The full license is in the file COPYING.txt, distributed with this software.
-#-----------------------------------------------------------------------------
-
-from matplotlib import figure
-import shutil
-import tempfile
-import numpy as np
-import os
-
-from yt.funcs import *
-
-from yt.config import ytcfg
-from yt.data_objects.profiles import \
-    BinnedProfile1D, \
-    BinnedProfile2D
-from yt.utilities.definitions import \
-    axis_names, inv_axis_names, x_dict, y_dict
-from .plot_types import \
-    FixedResolutionPlot, \
-    PCSlicePlot, \
-    PCSlicePlotNaturalNeighbor, \
-    PCProjectionPlot, \
-    PCProjectionPlotNaturalNeighbor, \
-    CuttingPlanePlot, \
-    ParticlePlot, \
-    ProfilePlot, \
-    Profile1DPlot, \
-    PhasePlot, \
-    LineQueryPlot, \
-    ScatterPlot
-from yt.utilities.minimal_representation import \
-    MinimalImageCollectionData
-
-# No better place to put this
-def concatenate_pdfs(output_fn, input_fns):
-    from pyPdf import PdfFileWriter, PdfFileReader
-    outfile = PdfFileWriter()
-    for fn in input_fns:
-        infile = PdfFileReader(open(fn, 'rb'))
-        outfile.addPage(infile.getPage(0))
-    outfile.write(open(output_fn, "wb"))
-
-class ImageCollection(object):
-    def __init__(self, pf, name):
-        self.pf = pf
-        self.name = name
-        self.images = []
-        self.image_metadata = []
-
-    def add_image(self, fn, descr):
-        self.image_metadata.append(descr)
-        self.images.append((os.path.basename(fn), np.fromfile(fn, dtype='c')))
-
-class PlotCollection(object):
-    r"""The PlotCollection object was created to ease the creation of multiple
-    slices, projections and so forth made from a single parameter file.
-    The concept is that when the width on one image changes, it should
-    change on all the others.  The PlotCollection can create all plot types
-    available in yt.
-
-    Parameters
-    ----------
-    pf : `Dataset`
-        The parameter file from which all the plots will be created.
-    center : array_like, optional
-        The 'center' supplied to plots like sphere plots, slices, and so
-        on.  Should be 3 elements.  Defaults to the point of maximum
-        density.
-    Long_variable_name : {'hi', 'ho'}, optional
-        Choices in brackets, default first when optional.
-
-    Notes
-    -----
-    This class is the primary entry point to creating plots, but it is not
-    the only entry point.  Additionally, creating a PlotCollection should
-    be a "cheap" operation.
-
-    You may iterate over the plots in the PlotCollection, via something
-    like:
-
-    >>> pc = PlotCollection(pf)
-    >>> for p in pc: print p
-
-    Examples
-    --------
-
-    >>> pc = PlotCollection(pf, center=[0.5, 0.5, 0.5])
-    >>> pc.add_slice("Density", 'x')
-    >>> pc.save()
-
-    """
-
-    __id_counter = 0
-    def __init__(self, pf, center=None):
-        self.plots = []
-        self.pf = pf
-        if center == None:
-            v,self.c = pf.h.find_max("Density") # @todo: ensure no caching
-        elif center == "center" or center == "c":
-            self.c = (pf.domain_right_edge + pf.domain_left_edge)/2.0
-        else:
-            self.c = np.array(center, dtype='float64')
-        mylog.info("Created plot collection with default plot-center = %s",
-                    list(self.c))
-
-    def __iter__(self):
-        for p in self.plots:
-            yield p
-
-    @property
-    def _mrep(self):
-        ic = ImageCollection(self.pf, "Plot Collection with center %s" % self.c)
-        dd = tempfile.mkdtemp()
-        fns = self.save(os.path.join(dd, "temp"))
-        for fn, p in zip(fns, self.plots):
-            ic.add_image(fn, p._pretty_name())
-        shutil.rmtree(dd)
-        return MinimalImageCollectionData(ic)
-
-    def hub_upload(self):
-        self._mrep.upload()
-
-    def save(self, basename=None, format="png", override=False, force_save=False):
-        r"""Save out all the plots hanging off this plot collection, using
-        generated names.
-
-        This function will create names for every plot that belongs to the
-        PlotCollection and save them out.  The names will, by default, be
-        prefixed with the name of the affiliate parameter file, and the file
-        names should indicate clearly what each plot represents.
-
-        Parameters
-        ----------
-        basename : string, optional
-            The prefix for all of the plot filenames.
-        format : string, optional
-            The plot file format.  Can be 'png', 'pdf', 'eps', 'jpg', or
-            anything else that matplotlib understands.
-        override : boolean
-            If this is true, then no generated filenames will be appended to
-            the base name.  You probably don't want this.
-        force_save : boolean
-            In parallel, only the root task (proc 0) saves an image, unless
-            this is set to True.
-
-        Returns
-        -------
-        items : string
-            This function returns a list of the filenames created.
-
-        Examples
-        --------
-
-        >>> fns = pc.save()
-        >>> for fn in fns: print "Saved", fn
-        """
-        if basename is None: basename = str(self.pf)
-        fn = []
-        for plot in self.plots:
-            fn.append(plot.save_image(basename, format=format, 
-                      override=override, force_save=force_save))
-            mylog.info("Saved %s", fn[-1])
-        if ytcfg.getboolean("yt", "__withinreason"):
-            from yt.gui.reason.bottle_mods import PayloadHandler
-            import base64
-            ph = PayloadHandler()
-            for f in fn:
-                if not f.endswith('png'): continue
-                img_data = base64.b64encode(open(f,'rb').read())
-                payload = {'type':'png_string',
-                           'image_data':img_data}
-                ph.add_payload(payload)
-        return fn
-
-    def set_xlim(self, xmin, xmax):
-        r"""Set the x-limits of all plots.
-
-        set_xlim on all plots is called with the parameters passed to this
-        function.
-
-        Parameters
-        ----------
-        xmin : float
-            The left boundary for the x axis.
-        xmax : float
-            The right boundary for the x axis.
-        """
-        for plot in self.plots:
-            plot.set_xlim(xmin, xmax)
-
-    def set_ylim(self, ymin, ymax):
-        r"""Set the y-limits of all plots.
-
-        set_ylim on all plots is called with the parameters passed to this
-        function.
-
-        Parameters
-        ----------
-        ymin : float
-            The left boundary for the x axis.
-        ymax : float
-            The right boundary for the x axis.
-        """
-        for plot in self.plots:
-            plot.set_ylim(ymin, ymax)
-
-    def set_zlim(self, zmin, zmax, *args, **kwargs):
-        """
-        Set the limits of the colorbar. 'min' or 'max' are possible inputs 
-        when combined with dex=value, where value gives the maximum number of 
-        dex to go above/below the min/max.  If value is larger than the true
-        range of values, min/max are limited to true range.
-
-        Only ONE of the following options can be specified. If all 3 are
-        specified, they will be used in the following precedence order:
-
-        * ``ticks`` - a list of floating point numbers at which to put ticks
-        * ``minmaxtick`` - display DEFAULT ticks with min & max also displayed
-        * ``nticks`` - if ticks not specified, can automatically determine a
-          number of ticks to be evenly spaced in log space
-        """
-        for plot in self.plots:
-            plot.set_autoscale(False)
-            plot.set_zlim(zmin, zmax, *args, **kwargs)
-
-    def set_lim(self, lim):
-        r"""Set the x- and y-limits of all plots.
-
-        set_xlim on all plots is called with the parameters passed to this
-        function, and then set_ylim is called.
-
-        Parameters
-        ----------
-        lim : tuple of floats
-            (xmin, xmax, ymin, ymax)
-        """
-        for plot in self.plots:
-            plot.set_xlim(*lim[:2])
-            plot.set_ylim(*lim[2:])
-
-    def autoscale(self):
-        r"""Turn on autoscaling on all plots.
-
-        This has the same effect as:
-
-        >>> for p in pc: p.set_autoscale(True)
-
-        By default, all plots are autoscaled until the colorbar is set
-        manually.  This turns autoscaling back on.  The colors may not be
-        updated unless _redraw_image is called on the plots, which should occur
-        with a change in the width or saving of images.
-        """
-        for plot in self.plots:
-            plot.set_autoscale(True)
-
-    def set_width(self, width, unit):
-        r"""Change the width of all image plots.
-
-        This function changes all the widths of the image plots (but notably
-        not any phase plots or profile plots) to be a given physical extent.
-
-        Parameters
-        ----------
-        width : float
-            The numeric value of the new width.
-        unit : string
-            The unit in which the given width is expressed.
-        """
-        for plot in self.plots:
-            plot.set_width(width, unit)
-
-    def set_cmap(self, cmap):
-        r"""Change the colormap of all plots.
-
-        This function will update the colormap on all plots for which a
-        colormap makes sense.  The colors may not be updated unless
-        _redraw_image is called on the plots, which should occur with a change
-        in the width or saving of images.
-
-        Parameters
-        ----------
-        cmap : string
-            An acceptable colormap.  See either yt.visualization.color_maps or
-            http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
-        """
-        for plot in self.plots:
-            plot.set_cmap(cmap)
-
-    def switch_field(self, field):
-        r"""Change the displayed of all image plots.
-
-        All images that display a field -- slices, cutting planes, projections
-        -- will be switched to display the specified field.  For projections,
-        this will re-generate the projection, if it is unable to load the
-        projected field off-disk.
-
-        Parameters
-        ----------
-        field : string
-            Any field that can be generated or read from disk.
-        """
-        for plot in self.plots:
-            plot.switch_z(field)
-    switch_z = switch_field
-
-    def _add_plot(self, plot):
-        r"""This function adds a plot to the plot collection.
-
-        This function is typically used internally to add a plot on to the
-        current list of plots.  However, if you choose to manually create a
-        plot, this can be used to add it to a collection for convenient
-        modification.
-
-        Parameters
-        ----------
-        plot : `yt.visualization.plot_types.RavenPlot`
-            A plot, which will be appended to the list of plots handled by this
-            plot collection.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.RavenPlot`
-            The plot handed to the function is passed back through.  This is
-            unnecessary, but is done for historical reasons.
-        """
-        self.plots.append(plot)
-        return plot
-
-    def add_slice(self, field, axis, coord=None, center=None,
-                 use_colorbar=True, figure = None, axes = None, fig_size=None,
-                 periodic = True, obj = None, field_parameters = None):
-        r"""Create a slice, from that a slice plot, and add it to the current
-        collection.
-
-        This function will generate a `yt.data_objects.api.YTSliceBase` from the given
-        parameters.  This slice then gets passed to a `yt.visualization.plot_types.PCSlicePlot`, and
-        the resultant plot is added to the current collection.  Various
-        parameters allow control of the way the slice is displayed, as well as
-        how the slice is generated.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        axis : int
-            The axis along which to slice.  Can be 0, 1, or 2 or x, y, z.
-        coord : float, optional
-            The coordinate to place the slice at, along the slicing axis.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        periodic : boolean, optional
-            By default, the slices are assumed to be periodic, and they will
-            wrap around the edges.
-        obj : `yt.data_objects.api.YTSliceBase`, optional
-            If you would like to use an existing slice, you may specify it
-            here, in which case a new slice will not be created.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PCSlicePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTSliceBase : This is the type created by this function and
-                                passed to the plot created here.
-
-        Notes
-        -----
-        This is the primary mechanism for creating slice plots, and generating
-        slice plots along multiple axes was the original purpose of the
-        PlotCollection.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_slice("Density", 'x')
-        """
-        axis = fix_axis(axis)
-        if center == None:
-            center = self.c
-        if coord == None:
-            coord = center[axis]
-        if obj is None:
-            if field_parameters is None: field_parameters = {}
-            obj = self.pf.index.slice(axis, coord, center=center,
-                            field_parameters = field_parameters)
-        p = self._add_plot(PCSlicePlot(
-                         obj, field, use_colorbar=use_colorbar,
-                         axes=axes, figure=figure,
-                         size=fig_size, periodic=periodic))
-        mylog.info("Added slice of %s at %s = %s with 'center' = %s", field,
-                    axis_names[axis], coord, list(center))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_particles(self, axis, width, p_size=1.0, col='k', stride=1.0,
-                      data_source=None, figure=None, axes=None):
-        r"""Create a plot of a thick slab of particles.
-
-        This function will generate a `yt.data_objects.api.YTRegionBase` from the given
-        parameters, and all particles which are within that region will be
-        plotted.
-
-        Parameters
-        ----------
-        axis : int
-            The axis along which to create the thick slab.  Can be 0, 1, or 2
-            or x, y, z.
-        width : float
-            The width of the thick slab, in code units, from which particles
-            will be plotted.
-        p_size : float, optional
-            The size of the points to be used to represent the particles, in
-            pixels.
-        col : color, optional
-            Specified in matplotlib color specifications, the color that
-            particles should be.
-        stride : float, optional
-            The stride through the particles to plot.  Used to plot every
-            fifth, every tenth, etc.  Note that the sorted order of particles
-            may result in a biased selection of particles.
-        data_source : `yt.data_objects.api.YTDataContainer`, optional
-            If specified, this will be the data source used for obtaining
-            particles.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ParticlePlot`
-            The plot that has been added to the PlotCollection.
-
-        Notes
-        -----
-        This plot type can be very expensive, and does not necessarily produce
-        the best visual results.  Plotting a large number of particles can be
-        very tricky, and often it's much better to instead use a slice or a
-        (thin) projection of deposited density, like particle_density_pyx.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_particles(0, 1.0)
-        """
-        axis = fix_axis(axis)
-        LE = self.pf.domain_left_edge.copy()
-        RE = self.pf.domain_right_edge.copy()
-        LE[axis] = self.c[axis] - width/2.0
-        RE[axis] = self.c[axis] + width/2.0
-        if data_source is None: data_source = self.pf.region(self.c, LE, RE)
-        data_source.axis = axis
-        p = self._add_plot(ParticlePlot(data_source, axis,
-                                        width, p_size, col, stride, figure,
-                                        axes))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_cutting_plane(self, field, normal,
-                          center=None, use_colorbar=True,
-                          figure = None, axes = None, fig_size=None, obj=None,
-                           field_parameters = None):
-        r"""Create a cutting plane, from that a plot, and add it to the current
-        collection.
-
-        A cutting plane is an oblique slice through the simulation volume,
-        oriented by a specified normal vector that is perpendicular to the
-        image plane.  This function will generate a
-        `yt.data_objects.api.YTCuttingPlaneBase` from the given parameters.  This cutting
-        plane then gets passed to a `yt.visualization.plot_types.CuttingPlanePlot`, and the
-        resultant plot is added to the current collection.  Various parameters
-        allow control of the way the slice is displayed, as well as how the
-        plane is generated.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        normal : array_like
-            The vector that defines the desired plane.  For instance, the
-            angular momentum of a sphere.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        obj : `YTCuttingPlaneBase`, optional
-            If you would like to use an existing cutting plane, you may specify
-            it here, in which case a new cutting plane will not be created.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the cutting plane upon
-            creation, which can be used for passing variables to derived
-            fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.CuttingPlanePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTCuttingPlaneBase : This is the type created by this function.
-
-        Notes
-        -----
-        This is the primary mechanism for creating cutting plane plots.  Note
-        that they are somewhat slow, but useful to orient the image in an
-        arbitrary direction.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        Here's a simple mechanism for getting the angular momentum of a
-        collapsing cloud and generating a cutting plane aligned with the
-        angular momentum vector.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> v, c = pf.h.find_max("Density")
-        >>> sp = pf.sphere(c, 1000.0/pf['au'])
-        >>> L = sp.quantities["AngularMomentumVector"]()
-        >>> pc = PlotCollection(pf)
-        >>> p = pc.add_cutting_plane("Density", L)
-        """
-        if center == None:
-            center = self.c
-        if not obj:
-            if field_parameters is None: field_parameters = {}
-            cp = self.pf.index.cutting(normal, center, 
-                    field_parameters = field_parameters)
-        else:
-            cp = obj
-        p = self._add_plot(CuttingPlanePlot(cp, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size))
-        mylog.info("Added plane of %s with 'center' = %s and normal = %s", field,
-                    list(center), list(normal))
-        p["Axis"] = "CuttingPlane"
-        return p
-
-    def add_projection(self, field, axis,  weight_field=None,
-                       data_source = None,
-                       center=None, use_colorbar=True,
-                       figure = None, axes = None, fig_size=None,
-                       periodic = True, obj = None, field_parameters = None):
-        r"""Create a projection, from that a projection plot, and add it to the
-        current collection.
-
-        This function will generate a `yt.data_objects.api.YTOverlapProjBase` from the given
-        parameters.  This projection then gets passed to a
-        `yt.visualization.plot_types.PCProjectionPlot`, and the resultant plot is added to the
-        current collection.  Various parameters allow control of the way the
-        slice is displayed, as well as how the slice is generated.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        axis : int
-            The axis along which to slice.  Can be 0, 1, or 2 or x, y, z.
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This is a data source respecting the `YTDataContainer` protocol (i.e., it
-            has grids and so forth) that will be used as input to the
-            projection.
-        weight_field : string
-            If specified, this will be the weighting field and the resultant
-            projection will be a line-of-sight average, defined as sum( f_i *
-            w_i * dl ) / sum( w_i * dl )
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        periodic : boolean, optional
-            By default, the slices are assumed to be periodic, and they will
-            wrap around the edges.
-        obj : `yt.data_objects.api.YTOverlapProjBase`, optional
-            If you would like to use an existing projection, you may specify it
-            here, in which case a new projection will not be created.  If this
-            option is specified the options data_source, weight_field and
-            field_parameters will be ignored.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PCProjectionPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTOverlapProjBase : This is the type created by this function and
-                               passed to the plot created here.
-
-        Notes
-        -----
-        This is the primary mechanism for creating projection plots, and
-        generating projection plots along multiple axes was the original
-        purpose of the PlotCollection.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_projection("Density", 'x', "Density")
-        """
-        axis = fix_axis(axis)
-        if field_parameters is None: field_parameters = {}
-        if center == None:
-            center = self.c
-        if obj is None:
-            obj = self.pf.index.proj(field, axis, weight_field,
-                                         data_source = data_source, center=center,
-                                         field_parameters = field_parameters)
-        p = self._add_plot(PCProjectionPlot(obj, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size, periodic=periodic))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_thin_projection(self, field, axis, thickness,
-                       weight_field=None, center=None, use_colorbar=True,
-                       figure = None, axes = None, fig_size=None,
-                       periodic = True, field_parameters = None):
-        r"""Create a projection through a thin slice of the domain, from that a
-        projection plot, and add it to the current collection.
-
-        This function will generate a rectangular prism region and supply it to
-        a`yt.data_objects.api.YTOverlapProjBase` from the given parameters.  This projection
-        then gets passed to a `yt.visualization.plot_types.PCProjectionPlot`, and the resultant plot
-        is added to the current collection.  Various parameters allow control
-        of the way the slice is displayed, as well as how the slice is
-        generated.  The center is used as the center of the thin projection.
-
-        Parameters
-        ----------
-        field : string
-            The initial field to slice and display.
-        axis : int
-            The axis along which to slice.  Can be 0, 1, or 2 or x, y, z.
-        thickness : float
-            In 'code units' this is the thickness of the region to be
-            projected through.
-        weight_field : string
-            If specified, this will be the weighting field and the resultant
-            projection will be a line-of-sight average, defined as sum( f_i *
-            w_i * dl ) / sum( w_i * dl )
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-        periodic : boolean, optional
-            By default, the slices are assumed to be periodic, and they will
-            wrap around the edges.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PCProjectionPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTOverlapProjBase : This is the type created by this function and
-                               passed to the plot created here.
-
-        Notes
-        -----
-        This is the primary mechanism for creating projection plots, and
-        generating projection plots along multiple axes was the original
-        purpose of the PlotCollection.
-
-        Note that all plots can be modified.  See `callback_list` for more
-        information.
-
-        Examples
-        --------
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_thin_projection("Density", 0, 0.1, "Density")
-        """
-        axis = fix_axis(axis)
-        if field_parameters is None: field_parameters = {}
-        if center == None:
-            center = self.c
-        LE = self.pf.domain_left_edge.copy()
-        RE = self.pf.domain_right_edge.copy()
-        LE[axis] = RE[axis] = center[axis]
-        LE[axis] -= thickness/2.0
-        RE[axis] += thickness/2.0
-        region = self.pf.region(center, LE, RE)
-        obj = self.pf.index.proj(field, axis, weight_field,
-                                     data_source = region, center=center,
-                                     field_parameters = field_parameters)
-        p = self._add_plot(PCProjectionPlot(obj, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size, periodic=periodic))
-        p["Axis"] = axis_names[axis]
-        return p
-
-    def add_profile_object(self, data_source, fields,
-                           weight="CellMassMsun", accumulation=False,
-                           x_bins=128, x_log=True, x_bounds=None,
-                           id=None, figure=None, axes=None):
-        r"""From an existing object, create a 1D, binned profile.
-
-        This function will accept an existing `YTDataContainer` source and from that,
-        it will generate a `Binned1DProfile`, based on the specified options.
-        This is useful if you have extracted a region, or if you wish to bin
-        some set of massages data -- or even if you wish to bin anything other
-        than a sphere.  The profile will be 1D, which means while it can have
-        an arbitrary number of fields, those fields will all be binned based on
-        a single field.
-
-        Parameters
-        ----------
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This is a data source respecting the `YTDataContainer` protocol (i.e., it
-            has grids and so forth) that will be used as input to the profile
-            generation.
-        fields : list of strings
-            The first element of this list is the field by which we will bin;
-            all subsequent fields will be binned and their profiles added to
-            the underlying `BinnedProfile1D`.
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : boolean, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.
-        x_bins : int, optional
-            How many bins should there be in the independent variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ProfilePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile1D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-
-        Examples
-        --------
-
-        >>> reg = pf.region([0.1, 0.2, 0.3], [0.0, 0.1, 0.2],
-                              [0.2, 0.3, 0.4])
-        >>> pc.add_profile_object(reg, ["Density", "Temperature"])
-        """
-        if x_bounds is None:
-            x_min, x_max = data_source.quantities["Extrema"](
-                            fields[0], non_zero = x_log)[0]
-        else:
-            x_min, x_max = x_bounds
-        profile = BinnedProfile1D(data_source,
-                                  x_bins, fields[0], x_min, x_max, x_log)
-        if len(fields) > 1:
-            profile.add_fields(fields[1:], weight=weight, accumulation=accumulation)
-        if id is None: id = self._get_new_id()
-        p = self._add_plot(Profile1DPlot(profile, fields, id,
-                                                   axes=axes, figure=figure))
-        return p
-
-    def add_profile_sphere(self, radius, unit, fields, center = None,
-                           weight="CellMassMsun", accumulation=False,
-                           x_bins=128, x_log=True, x_bounds=None,
-                           id=None, figure=None, axes=None):
-        r"""From a description of a sphere, create a 1D, binned profile.
-
-        This function will accept the radius of a sphere, and from that it will
-        generate a `Binned1DProfile`, based on the specified options.  The
-        profile will be 1D, which means while it can have an arbitrary number
-        of fields, those fields will all be binned based on a single field.
-
-        All subsequent parameters beyond "unit" will be passed verbatim to
-        add_profile_object.
-
-        Parameters
-        ----------
-        radius : float
-            The radius of the sphere to generate.
-        unit : string
-            The unit in which the given radius is expressed.
-        fields : list of strings
-            The first element of this list is the field by which we will bin;
-            all subsequent fields will be binned and their profiles added to
-            the underlying `BinnedProfile1D`.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : boolean, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.
-        x_bins : int, optional
-            How many bins should there be in the independent variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ProfilePlot`
-            The plot that has been added to the PlotCollection.  Note that the
-            underlying sphere may be accessed as .data.data_source
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile1D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-        yt.data_objects.api.YTSphereBase : This is the object auto-generated by this
-                                 function.
-
-        Examples
-        --------
-
-        >>> pc.add_profile_sphere(1.0, 'kpc', ["Density", "Electron_Fraction"])
-        """
-        if center is None:
-            center = self.c
-        r = radius/self.pf[unit]
-        sphere = self.pf.index.sphere(center, r)
-        p = self.add_profile_object(sphere, fields, weight, accumulation,
-                           x_bins, x_log, x_bounds, id,
-                           figure=figure, axes=axes)
-        p["Width"] = radius
-        p["Unit"] = unit
-        p["Axis"] = None
-        return p
-
-    def add_phase_object(self, data_source, fields, cmap=None,
-                               weight="CellMassMsun", accumulation=False,
-                               x_bins=128, x_log=True, x_bounds=None,
-                               y_bins=128, y_log=True, y_bounds=None,
-                               id=None, axes = None, figure = None,
-                               fractional=False):
-        r"""From an existing object, create a 2D, binned profile.
-
-        This function will accept an existing `YTDataContainer` source and from that,
-        it will generate a `Binned2DProfile`, based on the specified options.
-        This is useful if you have extracted a region, or if you wish to bin
-        some set of massages data -- or even if you wish to bin anything other
-        than a sphere.  The profile will be 2D, which means while it can have
-        an arbitrary number of fields, those fields will all be binned based on
-        two fields.
-
-        Parameters
-        ----------
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This is a data source respecting the `YTDataContainer` protocol (i.e., it
-            has grids and so forth) that will be used as input to the profile
-            generation.
-        fields : list of strings
-            The first element of this list is the field by which we will bin
-            into the x-axis, the second is the field by which we will bin onto
-            the y-axis.  All subsequent fields will be binned and their
-            profiles added to the underlying `BinnedProfile2D`.
-        cmap : string, optional
-            An acceptable colormap.  See either yt.visualization.color_maps or
-            http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : list of booleans, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.  The first value is for the
-            x-axis, the second value for the y-axis.  Note that accumulation
-            will only be along each row or column.
-        x_bins : int, optional
-            How many bins should there be in the x-axis variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        y_bins : int, optional
-            How many bins should there be in the y-axis variable?
-        y_log : boolean, optional
-            Should the bin edges be log-spaced?
-        y_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fractional : boolean
-            If true, the plot will be normalized to the sum of all the binned
-            values.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PlotTypes.PhasePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile2D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-        
-        Examples
-        --------
-        This will show the mass-distribution in the Density-Temperature plane.
-        
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> reg = pf.region([0.1, 0.2, 0.3], [0.0, 0.1, 0.2],
-        ...                   [0.2, 0.3, 0.4])
-        >>> pc.add_phase_object(reg, ["Density", "Temperature", "CellMassMsun"],
-        ...                     weight = None)
-        """
-        if x_bounds is None:
-            x_min, x_max = data_source.quantities["Extrema"](
-                                    fields[0], non_zero = x_log)[0]
-        else:
-            x_min, x_max = x_bounds
-        if y_bounds is None:
-            y_min, y_max = data_source.quantities["Extrema"](
-                                    fields[1], non_zero = y_log)[0]
-        else:
-            y_min, y_max = y_bounds
-        profile = BinnedProfile2D(data_source,
-                                  x_bins, fields[0], x_min, x_max, x_log,
-                                  y_bins, fields[1], y_min, y_max, y_log)
-        # This will add all the fields to the profile object
-        if len(fields)>2:
-            profile.add_fields(fields[2:], weight=weight,
-                    accumulation=accumulation, fractional=fractional)
-
-        if id is None: id = self._get_new_id()
-        p = self._add_plot(PhasePlot(profile, fields, 
-                                               id, cmap=cmap,
-                                               figure=figure, axes=axes))
-        return p
-
-    def add_phase_sphere(self, radius, unit, fields, center = None, cmap=None,
-                         weight="CellMassMsun", accumulation=False,
-                         x_bins=128, x_log=True, x_bounds=None,
-                         y_bins=128, y_log=True, y_bounds=None,
-                         id=None, axes = None, figure = None,
-                         fractional=False):
-        r"""From a description of a sphere, create a 2D, binned profile.
-
-        This function will accept the radius of a sphere, and from that it will
-        generate a `Binned1DProfile`, based on the specified options.  The
-        profile will be 2D, which means while it can have an arbitrary number
-        of fields, those fields will all be binned based on two fields.
-
-        All subsequent parameters beyond "unit" will be passed verbatim to
-        add_profile_object.
-
-        Parameters
-        ----------
-        radius : float
-            The radius of the sphere to generate.
-        unit : string
-            The unit in which the given radius is expressed.
-        fields : list of strings
-            The first element of this list is the field by which we will bin
-            into the y-axis, the second is the field by which we will bin onto
-            the y-axis.  All subsequent fields will be binned and their
-            profiles added to the underlying `BinnedProfile2D`.
-        center : array_like, optional
-            The center to be used for things like radius and radial velocity.
-            Defaults to the center of the plot collection.
-        cmap : string, optional
-            An acceptable colormap.  See either yt.visualization.color_maps or
-            http://www.scipy.org/Cookbook/Matplotlib/Show_colormaps .
-        weight : string, default "CellMassMsun"
-            The weighting field for an average.  This defaults to mass-weighted
-            averaging.
-        accumulation : list of booleans, optional
-            If true, from the low-value to the high-value the values in all
-            binned fields will be accumulated.  This is useful for instance
-            when adding an unweighted CellMassMsun to a radial plot, as it will
-            show mass interior to that radius.  The first value is for the
-            x-axis, the second value for the y-axis.  Note that accumulation
-            will only be along each row or column.
-        x_bins : int, optional
-            How many bins should there be in the x-axis variable?
-        x_log : boolean, optional
-            Should the bin edges be log-spaced?
-        x_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        y_bins : int, optional
-            How many bins should there be in the y-axis variable?
-        y_log : boolean, optional
-            Should the bin edges be log-spaced?
-        y_bounds : tuple of floats, optional
-            If specified, the boundary values for the binning.  If unspecified,
-            the min/max from the data_source will be used.  (Non-zero min/max
-            in case of log-spacing.)
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fractional : boolean
-            If true, the plot will be normalized to the sum of all the binned
-            values.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.PhasePlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.profiles.BinnedProfile2D : This is the object that does the
-                                   transformation of raw data into a 1D
-                                   profile.
-
-        Examples
-        --------
-
-        This will show the mass-distribution in the Density-Temperature plane.
-
-        >>> pc.add_phase_sphere(1.0, 'kpc',
-                ["Density", "Temperature", "CellMassMsun"], weight = None)
-        """
-
-        if center is None: center = self.c
-        r = radius/self.pf[unit]
-        data_source = self.pf.index.sphere(center, r)
-        p = self.add_phase_object(data_source, fields, cmap,
-                             weight, accumulation,
-                             x_bins, x_log, x_bounds,
-                             y_bins, y_log, y_bounds,
-                             id, axes=axes, figure=figure, fractional=fractional)
-        p["Width"] = radius
-        p["Unit"] = unit
-        p["Axis"] = None
-        return p
-
-    def add_scatter_source(self, data_source, fields, id=None,
-                     figure = None, axes = None, plot_options = None):
-        r"""Given a data source, make a scatter plot from that data source.
-
-        This is a very simple plot: you give it an instance of `YTDataContainer`, two
-        field names, and it will plot them on an axis
-
-        Parameters
-        ----------
-        data_source : `yt.data_objects.api.YTDataContainer`
-            This will be the data source from which field values will be
-            obtained.
-        fields : tuple of strings
-            The first of these will be the x-field, and the second the y-field.
-        id : int, optional
-            If specified, this will be the "semi-unique id" of the resultant
-            plot.  This should not be set.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        plot_options : dict
-            These options will be given to `matplotlib.axes.Axes.scatter`
-        
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.ScatterPlot`
-            The plot that has been added to the PlotCollection.
-
-        Notes
-        -----
-        This is a simpler way of making a phase plot, but note that because
-        pixels are deposited in order, the color may be a biased sample.
-
-        Examples
-        --------
-
-        >>> reg = pf.region([0.1, 0.2, 0.3], [0.0, 0.1, 0.2],
-                              [0.2, 0.3, 0.4])
-        >>> pc.add_scatter_plot(reg, ["Density", "Temperature"],
-        >>>                     plot_options = {'color':'b'})
-        """
-        if id is None: id = self._get_new_id()
-        if plot_options is None: plot_options = {}
-        sp = ScatterPlot(data_source, fields, id,
-                                   plot_options = plot_options,
-                                   figure=figure, axes=axes)
-        p = self._add_plot(sp)
-        return p
-
-    def add_fixed_resolution_plot(self, frb, field, use_colorbar=True,
-                      figure = None, axes = None, fig_size=None):
-        r"""Create a fixed resolution image from an existing buffer.
-
-        This accepts a `FixedResolutionBuffer` and will make a plot from that
-        buffer.
-
-        Parameters
-        ----------
-        frb : `yt.visualization.plot_types.FixedResolutionBuffer`
-            The buffer from which fields will be pulled.
-        field : string
-            The initial field to display.
-        use_colorbar : bool, optional
-            Whether we should leave room for and create a colorbar.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        fig_size : tuple of floats
-            This parameter can act as a proxy for the manual creation of a
-            figure.  By specifying it, you can create plots with an arbitrarily
-            large or small size.  It is in inches, defaulting to 100 dpi.
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.FixedResolutionPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.extensions.image_writer.write_image : A faster, colorbarless way to
-                                                 write out FRBs.
-
-        Examples
-        --------
-
-        Here's a simple mechanism for getting the angular momentum of a
-        collapsing cloud and generating a cutting plane aligned with the
-        angular momentum vector.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> proj = pf.proj("Density", 0)
-        >>> frb = FixedResolutionBuffer(proj, (0.2, 0.3, 0.4, 0.5), (512, 512))
-        >>> p = pc.add_fixed_resolution_plot(frb, "Density")
-        """
-        p = self._add_plot(FixedResolutionPlot(frb, field,
-                         use_colorbar=use_colorbar, axes=axes, figure=figure,
-                         size=fig_size))
-        p["Axis"] = "na"
-        return p
-
-    def add_ortho_ray(self, axis, coords, field, figure = None,
-                      axes = None, field_parameters = None,
-                      plot_options = None):
-        r"""Create a ray parallel to some axis, from that a line plot, and add
-        it to the current collection.
-
-        This function will generate a `yt.data_objects.api.YTOrthoRayBase` from the given
-        parameters.  This ray then gets passed to a `yt.visualization.plot_types.LineQueryPLot`, and
-        the resultant plot is added to the current collection.  Various
-        parameters allow control of the way the line plot is displayed, as well as
-        how the ray is generated.
-
-        Parameters
-        ----------
-        axis : int
-            The axis along which to cast the ray.  Can be 0, 1, or 2 or x, y,
-            z.
-        coords : tuple of floats
-            The coordinates to place the ray at.  Note that the axes are in the
-            form of x_dict[axis] and y_dict[axis] for some axis.
-        field : string
-            The initial field to slice and display.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-        plot_options : dict
-            These options will be given to `matplotlib.axes.Axes.plot`
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.LineQueryPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTOrthoRayBase : This is the type created by this function and
-                                   passed to the plot created here.
-
-        Examples
-        --------
-
-        This will cast a ray from (0.0, 0.5, 0.5) to (1.0, 0.5, 0.5) and plot
-        it.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_ortho_ray(0, (0.5, 0.5), "Density")
-        """
-        axis = fix_axis(axis)
-        if field_parameters is None: field_parameters = {}
-        if plot_options is None: plot_options = {}
-        data_source = self.pf.ortho_ray(axis, coords, 
-                        field_parameters = field_parameters)
-        p = self._add_plot(LineQueryPlot(data_source,
-                [axis_names[axis], field], self._get_new_id(),
-                figure=figure, axes=axes, plot_options=plot_options))
-        return p
-
-    def add_ray(self, start_point, end_point, field, figure = None,
-                axes = None, field_parameters = None, plot_options = None):
-        r"""Create a ray between two points, from that a line plot, and add
-        it to the current collection.
-
-        This function will generate a `yt.data_objects.api.YTRayBase` from the given
-        parameters.  This ray then gets passed to a `yt.visualization.plot_types.LineQueryPLot`, and
-        the resultant plot is added to the current collection.  Various
-        parameters allow control of the way the line plot is displayed, as well as
-        how the ray is generated.
-
-        Parameters
-        ----------
-        start_point : array_like
-            The starting point of the ray.
-        end_point : array_like
-            The ending point of the ray.
-        field : string
-            The initial field to slice and display.
-        figure : `matplotlib.figure.Figure`, optional
-            The figure onto which the axes will be placed.  Typically not used
-            unless *axes* is also specified.
-        axes : `matplotlib.axes.Axes`, optional
-            The axes object which will be used to create the image plot.
-            Typically used for things like multiplots and the like.
-        field_parameters : dict, optional
-            This set of parameters will be passed to the slice upon creation,
-            which can be used for passing variables to derived fields.
-        plot_options : dict
-            These options will be given to `matplotlib.axes.Axes.plot`
-
-        Returns
-        -------
-        plot : `yt.visualization.plot_types.LineQueryPlot`
-            The plot that has been added to the PlotCollection.
-
-        See Also
-        --------
-        yt.data_objects.api.YTRayBase : This is the type created by this function and
-                              passed to the plot created here.
-
-        Examples
-        --------
-
-        This will cast a ray from (0.1, 0.2, 0.3) to (0.9, 0.7, 0.4) and plot
-        it.
-
-        >>> pf = load("RD0005-mine/RedshiftOutput0005")
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> p = pc.add_ray((0.1, 0.2, 0.3), (0.9, 0.7, 0.4), "Density")
-        """
-        if field_parameters is None: field_parameters = {}
-        if plot_options is None: plot_options = {}
-        data_source = self.pf.ray(start_point, end_point, 
-                                    field_parameters = field_parameters)
-        p = self._add_plot(LineQueryPlot(data_source,
-                ['t', field], self._get_new_id(),
-                figure=figure, axes=axes, plot_options=plot_options))
-        return p
-
-    def _get_new_id(self):
-        self.__id_counter += 1
-        return self.__id_counter-1
-
-    @rootonly
-    def save_book(self, filename, author = None, title = None, keywords = None,
-                  subject = None, creator = None, producer = None,
-                  creation_date = None):
-        r"""Save a multipage PDF of all the current plots, rather than
-        individual image files.
-
-        This function will utilize the matplotlib PDF backend to create a new
-        PDF, and for every plot that the PlotCollection currently has, it will
-        render a new page into that PDF.  The pages will be in the order of the
-        current plots.
-
-        Parameters
-        ----------
-        filename : string
-            The name of the PDF file to generate.  Note that it will be
-            overwritten, and '.pdf' will not be appended.
-        author : string, optional
-            The string to place in the metadata value of the PDF for 'author'.
-        title : string, optional
-            The string to place in the metadata value of the PDF for 'title'.
-        keywords : string, optional
-            The string to place in the metadata value of the PDF for 'keywords'.
-        subject : string, optional
-            The string to place in the metadata value of the PDF for 'subject'.
-        creator : string, optional
-            The string to place in the metadata value of the PDF for 'creator'.
-        producer : string, optional
-            The string to place in the metadata value of the PDF for 'producer'.
-        creation_date : string, optional
-            The string to place in the metadata value of the PDF for
-            'creation_date'.
-
-        Returns
-        -------
-        Nothing
-
-        Examples
-        --------
-        This will set up a new PlotCollection, add some plots, and then save it
-        as a PDF.
-
-        >>> pc = PlotCollection(pf, [0.5, 0.5, 0.5])
-        >>> pc.add_projection("Density", 'x')
-        >>> pc.add_projection("Density", 'y')
-        >>> pc.add_projection("Density", 'z')
-        >>> pc.set_width(0.5, 'pc')
-        >>> dd = pf.h.all_data()
-        >>> pc.add_phase_object(dd, ["Density", "Temperature", "CellMassMsun"],
-        ...                     weight = None)
-        >>> pc.save_book("my_plots.pdf", author="Yours Truly",
-        ...              title="Fun plots")
-        """
-        from matplotlib.backends.backend_pdf import PdfPages
-        outfile = PdfPages(filename)
-        for plot in self.plots:
-            plot.save_to_pdf(outfile)
-        pdf_keys = ['Title', 'Author', 'Subject', 'Keywords', 'Creator',
-            'Producer', 'CreationDate']
-        pdf_values = [title, author, subject, keywords, creator, producer,
-            creation_date]
-        metadata = outfile.infodict()
-        for key, val in zip(pdf_keys, pdf_values):
-            if isinstance(val, str):
-                metadata[key] = val
-        outfile.close()
-
-def wrap_pylab_newplot(func):
-    @wraps(func)
-    def pylabify(self, *args, **kwargs):
-        # Let's assume that axes and figure are not in the positional
-        # arguments -- probably safe!
-        new_fig = self.pylab.figure()
-        try:
-            new_fig.canvas.set_window_title("%s" % (self.pf))
-        except AttributeError:
-            pass
-        if 'axes' not in kwargs: kwargs['axes'] = self.pylab.gca()
-        if 'figure' not in kwargs: kwargs['figure'] = self.pylab.gcf()
-        retval = func(self, *args, **kwargs)
-        retval._redraw_image()
-        retval._fig_num = new_fig.number
-        self.pylab.draw()
-        return retval
-    return pylabify
-
-def wrap_pylab_show(func):
-    @wraps(func)
-    def pylabify(self, *args, **kwargs):
-        retval = func(self, *args, **kwargs)
-        fig_num = self.pylab.gcf().number
-        for p in self.plots:
-            self.pylab.figure(p._fig_num)
-            self.pylab.draw()
-        self.pylab.figure(fig_num)
-        return retval
-    return pylabify
-
-class _Interactify(type):
-    # All inherited methods get wrapped if they start with add_ or set_
-    # So anything inheriting this automatically gets set up; additional
-    # wrappings can be done manually.  Note that this does NOT modify
-    # methods that are only in the subclasses.
-    def __init__(cls, name, bases, d):
-        super(_Interactify, cls).__init__(name, bases, d)
-        for base in bases:
-            for attrname in dir(base):
-                if attrname in d: continue # If overridden, don't reset
-                attr = getattr(cls, attrname)
-                if type(attr) == types.MethodType:
-                    if attrname.startswith("add_"):
-                        setattr(cls, attrname, wrap_pylab_newplot(attr))
-                    elif attrname.startswith("set_"):
-                        setattr(cls, attrname, wrap_pylab_show(attr))
-
-class PlotCollectionInteractive(PlotCollection):
-    __metaclass__ = _Interactify
-
-    autoscale = wrap_pylab_show(PlotCollection.autoscale)
-    switch_field = wrap_pylab_show(PlotCollection.switch_field)
-
-    def __init__(self, *args, **kwargs):
-        import pylab
-        self.pylab = pylab
-        super(PlotCollectionInteractive, self).__init__(*args, **kwargs)
-
-    def redraw(self):
-        r"""Redraw all affiliated plots.
-
-        To ensure that any interactive windows are up to date, this function
-        can be called to redraw all images into them.
-        """
-        for plot in self.plots:
-            plot._redraw_image()
-        self.pylab.draw()
-
-    def clear_figures(self):
-        r"""Clear all interactive figures affiliated with this collection.
-
-        Because reusing figures between plot collections can be tricky,
-        occasionally they must be manually cleared to re-obtain empty figures
-        for future plotting.  This will clear all figures.
-        """
-        for plot in self.plots:
-            self.pylab.figure(plot._fig_num)
-            self.pylab.clf()
-
-    def interactive_zoom(self):
-        r"""Enter an interactive zooming session for all plots.
-
-        Use this to enter an interactive session where zoom factors
-        can be entered that are used to set the widths of the plot
-        collection.  This function has no arguments, but will return
-        the final width upon exit.
-
-        Caution: Tested and works with TkAgg and MacOSX backends.  Threaded
-        backends like Qt4Agg are likely to fail.
-
-        Controls:
-        Any numeric value: Zooms by this factor
-        0: Exit interactive zoom session
-        -1: Reset to width of 1.0 in code units
-        empty: zooms by previously entered factor.
-
-        Returns:
-        width: (float) The final width of the plot collection
-        """
-        print 'Enter Zoom Factor, 0 to exit, -1 to reset to width=1.0'
-        zfactor = 1.0
-        while(True):
-            new_zoom = raw_input('zoom:')
-            if new_zoom is not '':
-                try:
-                    zfactor = float(new_zoom)
-                except:
-                    print 'Please enter a valid number, or 0 to exit'
-                    continue
-            else:
-                print 'Using previous zoom value of %e' % zfactor
-            if zfactor == 0.0:
-                break
-            elif zfactor == -1.0:
-                self.set_width(1.0,'1')
-            else:
-                self.set_width(self.plots[0].__dict__['width']/zfactor,'1')
-        print 'Returning final width of %e' % self.plots[0].width
-        return self.plots[0].width
-
-class PlotCollectionIPython(PlotCollection):
-    def save(self, basename = None):
-        r"""Shows all the plots hanging off this plot collection in the IPython
-        web notebook.
-
-        This function will instruct the IPython web notebook to show its
-        images.
-
-        Examples
-        --------
-
-        >>> pc.save()
-        """
-        from ._mpl_imports import FigureCanvasAgg
-        from IPython.zmq.pylab.backend_inline import \
-            send_figure
-        if basename is None: basename = str(self.pf)
-        for plot in self.plots:
-            canvas = FigureCanvasAgg(plot._figure)
-            send_figure(plot._figure)
-
-def _MPLFixImage(data_source, image_obj, field, cbar, cls):
-    nx, ny = image_obj.get_size()
-    def f(axes):
-        x0, x1 = axes.get_xlim()
-        y0, y1 = axes.get_ylim()
-        frb = cls(data_source, (x0, x1, y0, y1), (nx, ny))
-        image_obj.set_data(frb[field])
-        mi, ma = frb[field].min(), frb[field].max()
-        cbar.norm.autoscale((mi, ma))
-        image_obj.set_extent([x0, x1, y0, y1])
-        cbar.update_bruteforce(image_obj)
-    return f
-
-def matplotlib_widget(data_source, field, npix):
-    r"""Create a widget from a data_source that uses the Matplotlib interaction
-    method to pan, zoom, and so on.
-
-    This is a simple way to take a yt data source, for instance a projection or
-    a slice, and to create a matplotlib view into it that you can pan and zoom.
-    It uses the matplotlib interaction engine to manage input and display.
-
-    Parameters
-    ----------
-    data_source : :class:`yt.data_objects.data_containers.YTOverlapProjBase` or :class:`yt.data_objects.data_containers.YTSliceBase`
-        This is the source to be pixelized, which can be a projection or a
-        slice.  
-    field : string
-        The field that you want to display in the window.
-    npix : int
-        The number of pixels on a side you want the image to be.
-
-    Examples
-    --------
-
-    >>> pf = load("DD0030/DD0030")
-    >>> p = pf.proj("Density", "z")
-    >>> matplotlib_widget(p, "Density", 1024)
-
-    """
-    import pylab
-    import matplotlib.colors
-    from .fixed_resolution import FixedResolutionBuffer, \
-            ObliqueFixedResolutionBuffer
-    pf = data_source.pf
-    if getattr(data_source, "axis", 4) < 3:
-        cls = FixedResolutionBuffer
-        ax = data_source.axis
-        extent = [pf.domain_left_edge[x_dict[ax]],
-                  pf.domain_right_edge[x_dict[ax]],
-                  pf.domain_left_edge[y_dict[ax]],
-                  pf.domain_right_edge[y_dict[ax]]]
-    else:
-        cls = ObliqueFixedResolutionBuffer
-        extent = [0.0, 1.0, 0.0, 1.0]
-    take_log = pf.field_info[field].take_log
-    if take_log:
-        norm = matplotlib.colors.LogNorm()
-    else:
-        norm = matplotlib.colors.Normalize()
-    ax = pylab.figure().gca()
-    ax.autoscale(False)
-    axi = ax.imshow(np.random.random((npix, npix)),
-                    extent = extent, norm = norm,
-                    origin = 'lower')
-    cb = pylab.colorbar(axi, norm = norm)
-    showme = _MPLFixImage(data_source, axi, field, cb, cls)
-    ax.callbacks.connect("xlim_changed", showme)
-    ax.callbacks.connect("ylim_changed", showme)
-    ax.set_xlim(extent[0], extent[1])
-    ax.set_ylim(extent[2], extent[3])
-    return ax

This diff is so big that we needed to truncate the remainder.

Repository URL: https://bitbucket.org/yt_analysis/yt/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.



More information about the yt-svn mailing list