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

commits-noreply at bitbucket.org commits-noreply at bitbucket.org
Mon Jul 14 10:57:41 PDT 2014


5 new commits in yt:

https://bitbucket.org/yt_analysis/yt/commits/678cb63ab333/
Changeset:   678cb63ab333
Branch:      yt-3.0
User:        ngoldbaum
Date:        2014-07-04 02:29:15
Summary:     Streamlining ProfilePlot and PhasePlot creation.
Affected #:  1 file

diff -r 92e343ce7927343b06b78443260c0ea4f2c6b3a1 -r 678cb63ab3330ae240532bb06c415a92bee516ea yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -31,15 +31,15 @@
     ImagePlotContainer, \
     log_transform, linear_transform
 from yt.data_objects.profiles import \
-     create_profile
+    create_profile
 from yt.utilities.exceptions import \
-     YTNotInsideNotebook
+    YTNotInsideNotebook
 from yt.utilities.logger import ytLogger as mylog
 import _mpl_imports as mpl
 from yt.funcs import \
-     ensure_list, \
-     get_image_suffix, \
-     get_ipython_api_version
+    ensure_list, \
+    get_image_suffix, \
+    get_ipython_api_version
 
 def get_canvas(name):
     suffix = get_image_suffix(name)
@@ -150,10 +150,6 @@
         A dictionary or list of dictionaries containing plot keyword 
         arguments.  For example, dict(color="red", linestyle=":").
         Default: None.
-    profiles : list of profiles
-        If not None, a list of profile objects created with 
-        `yt.data_objects.profiles.create_profile`.
-        Default: None.
 
     Examples
     --------
@@ -196,48 +192,37 @@
     z_log = None
     x_title = None
     y_title = None
-
     _plot_valid = False
 
-    def __init__(self, data_source, x_field, y_fields, 
+    def __init__(self, data_source, x_field, y_fields,
                  weight_field="cell_mass", n_bins=64,
                  accumulation=False, fractional=False,
-                 label=None, plot_spec=None, profiles=None):
-        self.y_log = {}
-        self.y_title = {}
-        self.x_log = None
-        if profiles is None:
-            self.profiles = [create_profile(data_source, [x_field],
-                                            n_bins=[n_bins],
-                                            fields=ensure_list(y_fields),
-                                            weight_field=weight_field,
-                                            accumulation=accumulation,
-                                            fractional=fractional)]
-        else:
-            self.profiles = ensure_list(profiles)
-        
-        self.label = sanitize_label(label, len(self.profiles))
+                 label=None, plot_spec=None):
 
-        self.plot_spec = plot_spec
-        if self.plot_spec is None:
-            self.plot_spec = [dict() for p in self.profiles]
-        if not isinstance(self.plot_spec, list):
-            self.plot_spec = [self.plot_spec.copy() for p in self.profiles]
+        profiles = [create_profile(data_source, [x_field],
+                                   n_bins=[n_bins],
+                                   fields=ensure_list(y_fields),
+                                   weight_field=weight_field,
+                                   accumulation=accumulation,
+                                   fractional=fractional)]
 
-        self.figures = FigureContainer()
-        self.axes = AxesContainer(self.figures)
-        self._setup_plots()
-        
+        if plot_spec is None:
+            plot_spec = [dict() for p in profiles]
+        if not isinstance(plot_spec, list):
+            plot_spec = [plot_spec.copy() for p in profiles]
+
+        ProfilePlot._initialize_instance(self, profiles, label, plot_spec)
+
     def save(self, name=None):
         r"""
-        Saves a 1d profile plot.
+         Saves a 1d profile plot.
 
-        Parameters
-        ----------
-        name : str
-            The output file keyword.
-        
-        """
+         Parameters
+         ----------
+         name : str
+             The output file keyword.
+
+         """
         if not self._plot_valid:
             self._setup_plots()
         unique = set(self.figures.values())
@@ -259,14 +244,15 @@
         if not suffix:
             suffix = ".png"
         canvas_cls = get_canvas(name)
+        fns = []
         for uid, fig in iters:
             if isinstance(uid, types.TupleType):
                 uid = uid[1]
             canvas = canvas_cls(fig)
-            fn = "%s_1d-Profile_%s_%s%s" % (prefix, xfn, uid, suffix)
-            mylog.info("Saving %s", fn)
-            canvas.print_figure(fn)
-        return self
+            fns.append("%s_1d-Profile_%s_%s%s" % (prefix, xfn, uid, suffix))
+            mylog.info("Saving %s", fns[-1])
+            canvas.print_figure(fns[-1])
+        return fns
 
     def show(self):
         r"""This will send any existing plots to the IPython notebook.
@@ -323,7 +309,7 @@
             for field, field_data in profile.items():
                 self.axes[field].plot(np.array(profile.x), np.array(field_data),
                                       label=self.label[i], **self.plot_spec[i])
-        
+
         # This relies on 'profile' leaking
         for fname, axes in self.axes.items():
             xscale, yscale = self._get_field_log(fname, profile)
@@ -338,27 +324,43 @@
         self._plot_valid = True
 
     @classmethod
+    def _initialize_instance(cls, obj, profiles, labels, plot_specs):
+        obj.y_log = {}
+        obj.y_title = {}
+        obj.x_log = None
+        obj.profiles = ensure_list(profiles)
+        obj.label = sanitize_label(labels, len(obj.profiles))
+        if plot_specs is None:
+            plot_specs = [dict() for p in obj.profiles]
+        obj.plot_spec = plot_specs
+        obj.figures = FigureContainer()
+        obj.axes = AxesContainer(obj.figures)
+        obj._setup_plots()
+        return obj
+
+    @classmethod
     def from_profiles(cls, profiles, labels=None, plot_specs=None):
         r"""
-        Instantiate a ProfilePlot object from a list of profiles 
-        created with `yt.data_objects.profiles.create_profile`.
+        Instantiate a ProfilePlot object from a list of profiles
+        created with :func:`~yt.data_objects.profiles.create_profile`.
 
         Parameters
         ----------
-        profiles : list of profiles
-            If not None, a list of profile objects created with 
-            `yt.data_objects.profiles.create_profile`.
+        profiles : a profile or list of profiles
+            A single profile or list of profile objects created with
+            :func:`~yt.data_objects.profiles.create_profile`.
         labels : list of strings
             A list of labels for each profile to be overplotted.
             Default: None.
         plot_specs : list of dicts
-            A list of dictionaries containing plot keyword 
+            A list of dictionaries containing plot keyword
             arguments.  For example, [dict(color="red", linestyle=":")].
             Default: None.
 
         Examples
         --------
 
+        >>> from yt import simulation
         >>> es = simulation("AMRCosmology.enzo", "Enzo")
         >>> es.get_time_series()
 
@@ -382,9 +384,8 @@
             raise RuntimeError("Profiles list and labels list must be the same size.")
         if plot_specs is not None and len(plot_specs) != len(profiles):
             raise RuntimeError("Profiles list and plot_specs list must be the same size.")
-        obj = cls(None, None, None, profiles=profiles, label=labels,
-                  plot_spec=plot_specs)
-        return obj
+        obj = cls.__new__(cls)
+        return cls._initialize_instance(obj, profiles, labels, plot_specs)
 
     @invalidate_plot
     def set_line_property(self, property, value, index=None):
@@ -602,7 +603,7 @@
         fractional = profile.fractional
         x_title = self.x_title or self._get_field_label(field_x, xfi, x_unit)
         y_title = self.y_title.get(field_y, None) or \
-                    self._get_field_label(field_y, yfi, y_unit, fractional)
+            self._get_field_label(field_y, yfi, y_unit, fractional)
 
         return (x_title, y_title)
 
@@ -656,9 +657,6 @@
     fontsize: int
         Font size for all text in the plot.
         Default: 18.
-    font_color : str
-        Color for all text in the plot.
-        Default: "black"
     figure_size : int
         Size in inches of the image.
         Default: 8 (8x8)
@@ -691,27 +689,32 @@
     def __init__(self, data_source, x_field, y_field, z_fields,
                  weight_field="cell_mass", x_bins=128, y_bins=128,
                  accumulation=False, fractional=False,
-                 profile=None, fontsize=18, font_color="black", figure_size=8.0):
-        self.plot_title = {}
-        self.z_log = {}
-        self.z_title = {}
-        self._initfinished = False
-        self.x_log = None
-        self.y_log = None
+                 fontsize=18, figure_size=8.0):
 
-        if profile is None:
-            profile = create_profile(data_source,
-               [x_field, y_field],
-               ensure_list(z_fields),
-               n_bins = [x_bins, y_bins],
-               weight_field = weight_field,
-               accumulation=accumulation,
-               fractional=fractional)
-        self.profile = profile
-        super(PhasePlot, self).__init__(data_source, figure_size, fontsize)
-        # This is a fallback, in case we forget.
-        self._setup_plots()
-        self._initfinished = True
+        profile = create_profile(
+            data_source,
+            [x_field, y_field],
+            ensure_list(z_fields),
+            n_bins=[x_bins, y_bins],
+            weight_field=weight_field,
+            accumulation=accumulation,
+            fractional=fractional)
+
+        type(self)._initialize_instance(self, data_source, profile, fontsize, figure_size)
+
+    @classmethod
+    def _initialize_instance(cls, obj, data_source, profile, fontsize, figure_size):
+        obj.plot_title = {}
+        obj.z_log = {}
+        obj.z_title = {}
+        obj._initfinished = False
+        obj.x_log = None
+        obj.y_log = None
+        obj.profile = profile
+        super(PhasePlot, obj).__init__(data_source, figure_size, fontsize)
+        obj._setup_plots()
+        obj._initfinished = True
+        return obj
 
     def _get_field_title(self, field_z, profile):
         pf = profile.data_source.pf
@@ -729,7 +732,7 @@
         x_title = self.x_title or self._get_field_label(field_x, xfi, x_unit)
         y_title = self.y_title or self._get_field_label(field_y, yfi, y_unit)
         z_title = self.z_title.get(field_z, None) or \
-                    self._get_field_label(field_z, zfi, z_unit, fractional)
+            self._get_field_label(field_z, zfi, z_unit, fractional)
         return (x_title, y_title, z_title)
 
     def _get_field_label(self, field, field_info, field_unit, fractional=False):
@@ -837,6 +840,41 @@
                     label.set_color(self._font_color)
         self._plot_valid = True
 
+    @classmethod
+    def from_profile(cls, profile, fontsize=18, figure_size=8.0):
+        r"""
+        Instantiate a PhasePlot object from a profile object created
+        with :func:`~yt.data_objects.profiles.create_profile`.
+
+        Parameters
+        ----------
+        profile : An instance of :class:`~yt.data_objects.profiles.ProfileND`
+             A single profile object.
+        fontsize : float
+             The fontsize to use, in points.
+        figure_size : float
+             The figure size to use, in inches.
+
+        Examples
+        --------
+
+        >>> import yt
+        >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+        >>> extrema = {
+        ... 'density': (1e-31, 1e-24),
+        ... 'temperature': (1e1, 1e8),
+        ... 'cell_mass': (1e-6, 1e-1),
+        ... }
+        >>> profile = yt.create_profile(ds.all_data(), ['density', 'temperature'],
+        ...                             fields=['cell_mass'],extrema=extrema,
+        ...                             fractional=True)
+        >>> ph = yt.PhasePlot.from_profile(profile)
+        >>> ph.save()
+        """
+        obj = cls.__new__(cls)
+        data_source = profile.data_source
+        return cls._initialize_instance(obj, data_source, profile, figure_size, fontsize)
+
     def save(self, name=None, mpl_kwargs=None):
         r"""
         Saves a 2d profile plot.


https://bitbucket.org/yt_analysis/yt/commits/63f99967988f/
Changeset:   63f99967988f
Branch:      yt-3.0
User:        ngoldbaum
Date:        2014-07-04 02:29:28
Summary:     Adding tests for ProfilePlot and PhasePlot.
Affected #:  3 files

diff -r 678cb63ab3330ae240532bb06c415a92bee516ea -r 63f99967988f131df43d39ddb3b809b9f88b8312 yt/testing.py
--- a/yt/testing.py
+++ b/yt/testing.py
@@ -1,5 +1,5 @@
 """
-
+Utilities to aid testing.
 
 
 """

diff -r 678cb63ab3330ae240532bb06c415a92bee516ea -r 63f99967988f131df43d39ddb3b809b9f88b8312 yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -61,7 +61,7 @@
     return image_type == os.path.splitext(fname)[1]
 
 
-TEST_FLNMS = [None, 'test.png', 'test.eps',
+TEST_FLNMS = [None, 'test', 'test.png', 'test.eps',
               'test.ps', 'test.pdf']
 M7 = "DD0010/moving7_0010"
 WT = "WindTunnel/windtunnel_4lev_hdf5_plt_cnt_0030"

diff -r 678cb63ab3330ae240532bb06c415a92bee516ea -r 63f99967988f131df43d39ddb3b809b9f88b8312 yt/visualization/tests/test_profile_plots.py
--- /dev/null
+++ b/yt/visualization/tests/test_profile_plots.py
@@ -0,0 +1,85 @@
+"""
+Testsuite for ProfilePlot and PhasePlot
+
+
+
+"""
+
+#-----------------------------------------------------------------------------
+# 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.
+#-----------------------------------------------------------------------------
+import itertools
+import os
+import tempfile
+import shutil
+import unittest
+from yt.data_objects.profiles import create_profile
+from yt.extern.parameterized import\
+    parameterized, param
+from yt.testing import fake_random_pf
+from yt.visualization.profile_plotter import \
+    ProfilePlot, PhasePlot
+from yt.visualization.tests.test_plotwindow import \
+    assert_fname, TEST_FLNMS
+
+class TestProfilePlotSave(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        fields = ('density', 'temperature', 'velocity_x', 'velocity_y',
+                  'velocity_z')
+        units = ('g/cm**3', 'K', 'cm/s', 'cm/s', 'cm/s')
+        test_ds = fake_random_pf(64, fields=fields, units=units)
+        regions = [test_ds.region([0.5]*3, [0.4]*3, [0.6]*3), test_ds.all_data()]
+        profiles = []
+        phases = []
+        pr_fields = [('density', 'temperature'), ('density', 'velocity_x'),
+                     ('temperature', 'cell_mass'), ('density', 'radius'),
+                     ('velocity_magnitude', 'cell_mass')]
+        ph_fields = [('density', 'temperature', 'cell_mass'),
+                     ('density', 'velocity_x', 'cell_mass'),
+                     ('radius', 'temperature', 'velocity_magnitude')]
+        for reg in regions:
+            for x_field, y_field in pr_fields:
+                profiles.append(ProfilePlot(reg, x_field, y_field))
+                profiles.append(ProfilePlot(reg, x_field, y_field,
+                                            fractional=True, accumulation=True))
+                p1d = create_profile(reg, x_field, y_field)
+                profiles.append(ProfilePlot.from_profiles(p1d))
+            for x_field, y_field, z_field in ph_fields:
+                # set n_bins to [16, 16] since matplotlib's postscript
+                # renderer is slow when it has to write a lot of polygons
+                phases.append(PhasePlot(reg, x_field, y_field, z_field,
+                                        x_bins=16, y_bins=16))
+                phases.append(PhasePlot(reg, x_field, y_field, z_field,
+                                        fractional=True, accumulation=True,
+                                        x_bins=16, y_bins=16))
+                p2d = create_profile(reg, [x_field, y_field], z_field,
+                                     n_bins=[16, 16])
+                phases.append(PhasePlot.from_profile(p2d))
+        cls.profiles = profiles
+        cls.phases = phases
+        cls.ds = test_ds
+
+    def setUp(self):
+        self.tmpdir = tempfile.mkdtemp()
+        self.curdir = os.getcwd()
+        os.chdir(self.tmpdir)
+
+    def tearDown(self):
+        os.chdir(self.curdir)
+        shutil.rmtree(self.tmpdir)
+
+    @parameterized.expand(param.explicit((fname, )) for fname in TEST_FLNMS)
+    def test_profile_plot(self, fname):
+        for p in self.profiles:
+            yield assert_fname(p.save(fname)[0])
+
+    @parameterized.expand(param.explicit((fname, )) for fname in TEST_FLNMS)
+    def test_phase_plot(self, fname):
+        for p in self.phases:
+            assert assert_fname(p.save(fname)[0])


https://bitbucket.org/yt_analysis/yt/commits/8bf473d2ff5e/
Changeset:   8bf473d2ff5e
Branch:      yt-3.0
User:        ngoldbaum
Date:        2014-07-13 22:44:29
Summary:     Merging with mainline tip.
Affected #:  36 files

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced .hgignore
--- a/.hgignore
+++ b/.hgignore
@@ -7,6 +7,7 @@
 rockstar.cfg
 yt_updater.log
 yt/frontends/artio/_artio_caller.c
+yt/analysis_modules/halo_finding/rockstar/rockstar_groupies.c
 yt/analysis_modules/halo_finding/rockstar/rockstar_interface.c
 yt/frontends/ramses/_ramses_reader.cpp
 yt/frontends/sph/smoothing_kernel.c

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced CREDITS
--- a/CREDITS
+++ b/CREDITS
@@ -2,15 +2,21 @@
 
 Contributors:   
                 Tom Abel (tabel at stanford.edu)
-                David Collins (dcollins at physics.ucsd.edu)
+                Gabriel Altay (gabriel.altay at gmail.com)
+                Kenza Arraki (karraki at gmail.com)
+                Alex Bogert (fbogert at ucsc.edu)
+                David Collins (dcollins4096 at gmail.com)
                 Brian Crosby (crosby.bd at gmail.com)
                 Andrew Cunningham (ajcunn at gmail.com)
+                Miguel de Val-Borro (miguel.deval at gmail.com)
                 Hilary Egan (hilaryye at gmail.com)
                 John Forces (jforbes at ucolick.org)
+                Sam Geen (samgeen at gmail.com)
                 Nathan Goldbaum (goldbaum at ucolick.org)
                 Markus Haider (markus.haider at uibk.ac.at)
                 Cameron Hummels (chummels at gmail.com)
                 Christian Karch (chiffre at posteo.de)
+                Ben W. Keller (kellerbw at mcmaster.ca)
                 Ji-hoon Kim (me at jihoonkim.org)
                 Steffen Klemer (sklemer at phys.uni-goettingen.de)
                 Kacper Kowalik (xarthisius.kk at gmail.com)
@@ -21,18 +27,23 @@
                 Chris Malone (chris.m.malone at gmail.com)
                 Josh Maloney (joshua.moloney at colorado.edu)
                 Chris Moody (cemoody at ucsc.edu)
+                Stuart Mumford (stuart at mumford.me.uk)
                 Andrew Myers (atmyers at astro.berkeley.edu)
                 Jill Naiman (jnaiman at ucolick.org)
+                Desika Narayanan (dnarayan at haverford.edu)
                 Kaylea Nelson (kaylea.nelson at yale.edu)
                 Jeff Oishi (jsoishi at gmail.com)
+                Brian O'Shea (bwoshea at gmail.com)
                 Jean-Claude Passy (jcpassy at uvic.ca)
+                John Regan (john.regan at helsinki.fi)
                 Mark Richardson (Mark.L.Richardson at asu.edu)
                 Thomas Robitaille (thomas.robitaille at gmail.com)
                 Anna Rosen (rosen at ucolick.org)
                 Douglas Rudd (drudd at uchicago.edu)
                 Anthony Scopatz (scopatz at gmail.com)
                 Noel Scudder (noel.scudder at stonybrook.edu)
-                Devin Silvia (devin.silvia at colorado.edu)
+                Pat Shriwise (shriwise at wisc.edu)
+                Devin Silvia (devin.silvia at gmail.com)
                 Sam Skillman (samskillman at gmail.com)
                 Stephen Skory (s at skory.us)
                 Britton Smith (brittonsmith at gmail.com)
@@ -42,8 +53,10 @@
                 Stephanie Tonnesen (stonnes at gmail.com)
                 Matthew Turk (matthewturk at gmail.com)
                 Rich Wagner (rwagner at physics.ucsd.edu)
+                Michael S. Warren (mswarren at gmail.com)
                 Andrew Wetzel (andrew.wetzel at yale.edu)
                 John Wise (jwise at physics.gatech.edu)
+                Michael Zingale (michael.zingale at stonybrook.edu)
                 John ZuHone (jzuhone at gmail.com)
 
 Several items included in the yt/extern directory were written by other

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced MANIFEST.in
--- a/MANIFEST.in
+++ b/MANIFEST.in
@@ -12,4 +12,3 @@
 prune tests
 graft yt/gui/reason/html/resources
 exclude clean.sh .hgchurn
-recursive-include yt/utilities/kdtree *.f90 *.v Makefile LICENSE

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/analyzing/analysis_modules/running_halofinder.rst
--- a/doc/source/analyzing/analysis_modules/running_halofinder.rst
+++ b/doc/source/analyzing/analysis_modules/running_halofinder.rst
@@ -300,40 +300,11 @@
 Therefore Parallel HOP is not a direct substitution for
 normal HOP, but is very similar.
 
-.. _fkd_setup:
-
-Fortran kD Tree Setup
-^^^^^^^^^^^^^^^^^^^^^
-
-Parallel HOP will not build automatically with yt. Please follow the instructions
-below in order to setup Parallel HOP.
-
-  #. Download `Forthon <http://hifweb.lbl.gov/Forthon/>`_. Extract the files
-     (e.g. tar -zxvf Forthon.tgz) and cd into the new Forthon directory. 
-     Making sure you're using the same version of python you use with yt, invoke
-     ``python setup.py install``.
-  #. Change directory to your yt source. Starting from the top level, cd into
-     ``yt/utilities/kdtree``.
-  #. Inside that directory, you should see these files:
-  
-     .. code-block:: bash
-     
-        % ls
-        Makefile        fKD.f90         fKD_source.f90
-        __init__.py     fKD.v           test.py
-  
-  #. Type ``make``. If that is successful, there should be a file in the
-     directory named ``fKDpy.so``. If there are problems, please contact the
-     `yt-users email list <http://lists.spacepope.org/listinfo.cgi/yt-users-spacepope.org>`_.
-  #. Go to the top level of the yt source directory, which from the ``kdtree``
-     directory is three levels up ``cd ../../..``, and invoke
-     ``python setup.py install``.
-  #. Parallel HOP should now work.
-     
-
 Running Parallel HOP
 ^^^^^^^^^^^^^^^^^^^^
 
+Note: This is probably broken now that the Fortran kdtree has been removed.
+
 In the simplest form, Parallel HOP is run very similarly to the other halo finders.
 In the example below, Parallel HOP will be run on a dataset with all the default
 values. Parallel HOP can be run in serial, but as mentioned above, it is

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/analyzing/units/2)_Data_Selection_and_fields.ipynb
--- a/doc/source/analyzing/units/2)_Data_Selection_and_fields.ipynb
+++ b/doc/source/analyzing/units/2)_Data_Selection_and_fields.ipynb
@@ -1,7 +1,7 @@
 {
  "metadata": {
   "name": "",
-  "signature": "sha256:b7541e0167001c6dd74306c8490385ace7bdb0533a829286f0505c0b24c67f16"
+  "signature": "sha256:882b31591c60bfe6ad4cb0f8842953d2e94fb8a12ce742be831a65642eea72c9"
  },
  "nbformat": 3,
  "nbformat_minor": 0,
@@ -325,8 +325,7 @@
      "input": [
       "from astropy import units as u\n",
       "x = 42.0 * u.meter\n",
-      "y = YTQuantity(x)\n",
-      "y2 = YTQuantity.from_astropy(x) # Another way to create the quantity"
+      "y = YTQuantity.from_astropy(x) "
      ],
      "language": "python",
      "metadata": {},
@@ -337,8 +336,7 @@
      "collapsed": false,
      "input": [
       "print x, type(x)\n",
-      "print y, type(y)\n",
-      "print y2, type(y2)"
+      "print y, type(y)"
      ],
      "language": "python",
      "metadata": {},
@@ -349,8 +347,7 @@
      "collapsed": false,
      "input": [
       "a = np.random.random(size=10) * u.km/u.s\n",
-      "b = YTArray(a)\n",
-      "b2 = YTArray.from_astropy(a) # Another way to create the quantity"
+      "b = YTArray.from_astropy(a)"
      ],
      "language": "python",
      "metadata": {},
@@ -361,8 +358,7 @@
      "collapsed": false,
      "input": [
       "print a, type(a)\n",
-      "print b, type(b)\n",
-      "print b2, type(b2)"
+      "print b, type(b)"
      ],
      "language": "python",
      "metadata": {},
@@ -438,7 +434,7 @@
      "collapsed": false,
      "input": [
       "k1 = kboltz.to_astropy()\n",
-      "k2 = YTQuantity(kb)\n",
+      "k2 = YTQuantity.from_astropy(kb)\n",
       "print k1 == k2"
      ],
      "language": "python",
@@ -449,7 +445,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "c = YTArray(a)\n",
+      "c = YTArray.from_astropy(a)\n",
       "d = c.to_astropy()\n",
       "print a == d"
      ],

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/cookbook/fits_radio_cubes.ipynb
--- a/doc/source/cookbook/fits_radio_cubes.ipynb
+++ b/doc/source/cookbook/fits_radio_cubes.ipynb
@@ -81,8 +81,7 @@
      "collapsed": false,
      "input": [
       "from yt.frontends.fits.misc import PlotWindowWCS\n",
-      "wcs_slc = PlotWindowWCS(slc)\n",
-      "wcs_slc[\"intensity\"]"
+      "PlotWindowWCS(slc)\n"
      ],
      "language": "python",
      "metadata": {},
@@ -99,7 +98,7 @@
      "cell_type": "code",
      "collapsed": false,
      "input": [
-      "wcs_slc.save()"
+      "slc.save()"
      ],
      "language": "python",
      "metadata": {},
@@ -463,4 +462,4 @@
    "metadata": {}
   }
  ]
-}
\ No newline at end of file
+}

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/cookbook/simple_plots.rst
--- a/doc/source/cookbook/simple_plots.rst
+++ b/doc/source/cookbook/simple_plots.rst
@@ -118,6 +118,8 @@
 
 .. yt_cookbook:: show_hide_axes_colorbar.py
 
+.. _matplotlib-primitives:
+
 Accessing and Modifying Plots Directly
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/reference/api/api.rst
--- a/doc/source/reference/api/api.rst
+++ b/doc/source/reference/api/api.rst
@@ -15,6 +15,7 @@
    ~yt.visualization.plot_window.OffAxisSlicePlot
    ~yt.visualization.plot_window.ProjectionPlot
    ~yt.visualization.plot_window.OffAxisProjectionPlot
+   ~yt.visualization.plot_window.WindowPlotMPL
 
 ProfilePlot and PhasePlot
 ^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -24,6 +25,7 @@
 
    ~yt.visualization.profile_plotter.ProfilePlot
    ~yt.visualization.profile_plotter.PhasePlot
+   ~yt.visualization.profile_plotter.PhasePlotMPL
 
 Fixed Resolution Pixelization
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/visualizing/_cb_docstrings.inc
--- a/doc/source/visualizing/_cb_docstrings.inc
+++ b/doc/source/visualizing/_cb_docstrings.inc
@@ -1,370 +1,445 @@
+Arrow callback
+~~~~~~~~~~~~~~
+
 .. function:: annotate_arrow(self, pos, code_size, plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.ArrowCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.ArrowCallback`.)
 
-   This adds an arrow pointing at *pos* with size
-   *code_size* in code units.  *plot_args* is a dict fed to
+   This adds an arrow pointing at ``pos`` with size
+   ``code_size`` in code units.  ``plot_args`` is a dict fed to
    matplotlib with arrow properties.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'), center='max')
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'), center='c')
    slc.annotate_arrow((0.5, 0.5, 0.5), (1, 'kpc'))
    slc.save()
 
--------------
+Clump Finder Callback
+~~~~~~~~~~~~~~~~~~~~~
 
 .. function:: annotate_clumps(self, clumps, plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.ClumpContourCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.ClumpContourCallback`.)
 
-   Take a list of *clumps* and plot them as a set of
+   Take a list of ``clumps`` and plot them as a set of
    contours.
 
 .. python-script::
 
-   from yt.mods import *
-   from yt.analysis_modules.level_sets.api import *
+   import yt
+   import numpy as np
+   from yt.analysis_modules.level_sets.api import \
+       Clump, find_clumps, get_lowest_clumps
 
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   data_source = pf.disk([0.5, 0.5, 0.5], [0., 0., 1.],
-                           (8., 'kpc'), (1., 'kpc'))
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   data_source = ds.disk([0.5, 0.5, 0.5], [0., 0., 1.],
+                         (8., 'kpc'), (1., 'kpc'))
 
    c_min = 10**np.floor(np.log10(data_source['density']).min()  )
    c_max = 10**np.floor(np.log10(data_source['density']).max()+1)
 
-   function = 'self.data[\'Density\'].size > 20'
+   function = 'self.data[\'density\'].size > 20'
    master_clump = Clump(data_source, None, 'density', function=function)
    find_clumps(master_clump, c_min, c_max, 2.0)
    leaf_clumps = get_lowest_clumps(master_clump)
 
-   prj = ProjectionPlot(pf, 2, 'density', center='c', width=(20,'kpc'))
+   prj = yt.ProjectionPlot(ds, 2, 'density', center='c', width=(20,'kpc'))
    prj.annotate_clumps(leaf_clumps)
    prj.save('clumps')
 
--------------
+Overplot Contours
+~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_contour(self, field, ncont=5, factor=4, take_log=False, clim=None, plot_args=None):
+.. function:: annotate_contour(self, field, ncont=5, factor=4, take_log=False,
+                               clim=None, plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.ContourCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.ContourCallback`.)
 
-   Add contours in *field* to the plot.  *ncont* governs the
-   number of contours generated, *factor* governs the number
-   of points used in the interpolation, *take_log* governs
-   how it is contoured and *clim* gives the (upper, lower)
-   limits for contouring.
+   Add contours in ``field`` to the plot.  ``ncont`` governs the number of
+   contours generated, ``factor`` governs the number of points used in the
+   interpolation, ``take_log`` governs how it is contoured and ``clim`` gives
+   the (upper, lower) limits for contouring.
 
 .. python-script::
-   
-   from yt.mods import *
-   pf = load("Enzo_64/DD0043/data0043")
-   s = SlicePlot(pf, "x", ["density"], center="max")
+
+   import yt
+   ds = yt.load("Enzo_64/DD0043/data0043")
+   s = yt.SlicePlot(ds, "x", "density", center="max")
    s.annotate_contour("temperature")
    s.save()
 
--------------
+Overplot quivers
+~~~~~~~~~~~~~~~~
+
+Axis-Aligned data sources
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+.. function:: annotate_quiver(self, field_x, field_y, factor, scale=None,
+                              scale_units=None, normalize=False):
+
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.QuiverCallback`.)
+
+   Adds a 'quiver' plot to any plot, using the ``field_x`` and ``field_y`` from
+   the associated data, skipping every ``factor`` datapoints ``scale`` is the
+   data units per arrow length unit using ``scale_units`` (see
+   matplotlib.axes.Axes.quiver for more info)
+
+.. python-script::
+
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.ProjectionPlot(ds, 'z', 'density', center=[0.5, 0.5, 0.5],
+                         weight_field='density', width=(20, 'kpc'))
+   p.annotate_quiver('velocity_x', 'velocity_y', 16)
+   p.save()
+
+Off-axis Data Sources
+^^^^^^^^^^^^^^^^^^^^^
 
 .. function:: annotate_cquiver(self, field_x, field_y, factor):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.CuttingQuiverCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.CuttingQuiverCallback`.)
 
-   Get a quiver plot on top of a cutting plane, using
-   *field_x* and *field_y*, skipping every *factor*
-   datapoint in the discretization.
+   Get a quiver plot on top of a cutting plane, using ``field_x`` and
+   ``field_y``, skipping every ``factor`` datapoint in the discretization.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("Enzo_64/DD0043/data0043")
-   s = OffAxisSlicePlot(pf, [1,1,0], ["density"], center="c")
+   import yt
+   ds = yt.load("Enzo_64/DD0043/data0043")
+   s = yt.OffAxisSlicePlot(ds, [1,1,0], ["density"], center="c")
    s.annotate_cquiver('cutting_plane_velocity_x', 'cutting_plane_velocity_y', 10)
    s.zoom(1.5)
    s.save()
 
--------------
+Overplot grids
+~~~~~~~~~~~~~~
 
-.. function:: annotate_grids(self, alpha=1.0, min_pix=1, annotate=False, periodic=True):
+.. function:: annotate_grids(self, alpha=1.0, min_pix=1, annotate=False,
+                             periodic=True):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.GridBoundaryCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.GridBoundaryCallback`.)
 
-   Adds grid boundaries to a plot, optionally with
-   *alpha*-blending. Cuttoff for display is at *min_pix*
-   wide. *annotate* puts the grid id in the corner of the
-   grid.  (Not so great in projections...)
+   Adds grid boundaries to a plot, optionally with alpha-blending via the
+   ``alpha`` keyword. Cuttoff for display is at ``min_pix`` wide. ``annotate``
+   puts the grid id in the corner of the grid.  (Not so great in projections...)
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'), center='max')
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'), center='max')
    slc.annotate_grids()
    slc.save()
 
--------------
+Overplot Halo Annotations
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_halos(self, halo_catalog, col='white', alpha =1, width= None):
+.. function:: annotate_halos(self, halo_catalog, col='white', alpha =1,
+                             width=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.HaloCatalogCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.HaloCatalogCallback`.)
 
-   Accepts a :class:`yt.HaloCatalog` *HaloCatalog* and plots 
-   a circle at the location of each halo with the radius of
-   the circle corresponding to the virial radius of the halo.
-   If *width* is set to None (default) all halos are plotted.
-   Otherwise, only halos that fall within a slab with width
-   *width* centered on the center of the plot data. The 
-   color and transparency of the circles can be controlled with
-   *col* and *alpha* respectively.
+   Accepts a :class:`yt.HaloCatalog` and plots a circle at the location of each
+   halo with the radius of the circle corresponding to the virial radius of the
+   halo.  If ``width`` is set to None (default) all halos are plotted.
+   Otherwise, only halos that fall within a slab with width ``width`` centered
+   on the center of the plot data. The color and transparency of the circles can
+   be controlled with ``col`` and ``alpha`` respectively.
 
 .. python-script::
-   
-   from yt.mods import *
+
+   import yt
    from yt.analysis_modules.halo_analysis.halo_catalog import HaloCatalog
 
-   data_pf = load('Enzo_64/RD0006/RedshiftOutput0006')
-   halos_pf = load('rockstar_halos/halos_0.0.bin')
+   data_ds = yt.load('Enzo_64/RD0006/RedshiftOutput0006')
+   halos_ds = yt.load('rockstar_halos/halos_0.0.bin')
 
-   hc = HaloCatalog(halos_pf=halos_pf)
+   hc = HaloCatalog(halos_pf=halos_ds)
    hc.create()
 
-   prj = ProjectionPlot(data_pf, 'z', 'density')
+   prj = yt.ProjectionPlot(data_ds, 'z', 'density')
    prj.annotate_halos(hc)
    prj.save()
 
--------------
+Overplot a Straight Line
+~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_image_line(self, p1, p2, data_coords=False, plot_args=None):
+.. function:: annotate_image_line(self, p1, p2, data_coords=False,
+                                  plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.ImageLineCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.ImageLineCallback`.)
 
-   Plot from *p1* to *p2* (normalized image plane coordinates) with
-   *plot_args* fed into the plot.
+   Plot from ``p1`` to ``p2`` (normalized image plane coordinates) with
+  ``plot_args`` fed into the plot.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, 'z', 'density', center='m', width=(10, 'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.ProjectionPlot(ds, 'z', 'density', center='m', width=(10, 'kpc'))
    p.annotate_image_line((0.3, 0.4), (0.8, 0.9), plot_args={'linewidth':5})
    p.save()
 
--------------
+Overplot a line plot
+~~~~~~~~~~~~~~~~~~~~
 
 .. function:: annotate_line(self, x, y, plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.LinePlotCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.LinePlotCallback`.)
 
-   Over plot *x* and *y* (in code units) with *plot_args* fed into the plot.
+   Over plot numpy arrays or lists ``x`` and ``y`` (in code units) with
+   ``plot_args`` fed into the plot.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, 'z', 'density', center='m', width=(10, 'kpc'))
-   p.annotate_line([-6, -4, -2, 0, 2, 4, 6], [3.6, 1.6, 0.4, 0, 0.4, 1.6, 3.6], plot_args={'linewidth':5})
+   import yt
+   import numpy as np
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.ProjectionPlot(ds, 'z', 'density', center='m', width=(20, 'kpc'))
+   x = np.array([-6, -4, -2, 0, 2, 4, 6])
+   y = x**2/10
+   p.annotate_line(x, y, plot_args={'linewidth':5})
    p.save()
 
--------------
+Overplot Magnetic Field Quivers
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_magnetic_field(self, factor=16, scale=None, scale_units=None, normalize=False):
+.. function:: annotate_magnetic_field(self, factor=16, scale=None,
+                                      scale_units=None, normalize=False):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.MagFieldCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.MagFieldCallback`.)
 
-   Adds a 'quiver' plot of magnetic field to the plot,
-   skipping all but every *factor* datapoint. *scale* is the
-   data units per arrow length unit using *scale_units* (see
-   matplotlib.axes.Axes.quiver for more info). if
-   *normalize* is True, the magnetic fields will be scaled
-   by their local (in-plane) length, allowing morphological
-   features to be more clearly seen for fields with
-   substantial variation in field strength.
+   Adds a 'quiver' plot of magnetic field to the plot, skipping all but every
+   ``factor`` datapoint. ``scale`` is the data units per arrow length unit using
+   ``scale_units`` (see matplotlib.axes.Axes.quiver for more info). if
+   ``normalize`` is ``True``, the magnetic fields will be scaled by their local
+   (in-plane) length, allowing morphological features to be more clearly seen
+   for fields with substantial variation in field strength.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("MHDSloshing/virgo_low_res.0054.vtk",
-             parameters={"TimeUnits":3.1557e13, "LengthUnits":3.0856e24,
-                         "DensityUnits":6.770424595218825e-27})
-   p = ProjectionPlot(pf, 'z', 'density', center='c', width=(300, 'kpc'))
+   import yt
+   ds = yt.load("MHDSloshing/virgo_low_res.0054.vtk",
+                parameters={"time_unit":(1, 'Myr'), "length_unit":(1, 'Mpc'),
+                            "mass_unit":(1e17, 'Msun')})
+   p = yt.ProjectionPlot(ds, 'z', 'density', center='c', width=(300, 'kpc'))
    p.annotate_magnetic_field()
    p.save()
 
--------------
+Annotate a Point With a Marker
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. function:: annotate_marker(self, pos, marker='x', plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.MarkerAnnotateCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.MarkerAnnotateCallback`.)
 
-   Adds text *marker* at *pos* in code coordinates.
-   *plot_args* is a dict that will be forwarded to the plot
+   Adds ``marker`` at ``pos`` in code coordinates.
+   ``plot_args`` is a dict that will be forwarded to the plot
    command.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   s = SlicePlot(pf, 'z', 'density', center='m', width=(10, 'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   s = yt.SlicePlot(ds, 'z', 'density', center='c', width=(10, 'kpc'))
    s.annotate_marker([0.5, 0.5, 0.5], plot_args={'s':10000})
-   s.save()   
+   s.save()
 
--------------
+Overplotting Particle Positions
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_particles(self, width, p_size=1.0, col='k', marker='o', stride=1.0, ptype=None, stars_only=False, dm_only=False, minimum_mass=None):
+.. function:: annotate_particles(self, width, p_size=1.0, col='k', marker='o',
+                                 stride=1.0, ptype=None, stars_only=False,
+                                 dm_only=False, minimum_mass=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.ParticleCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.ParticleCallback`.)
 
-   Adds particle positions, based on a thick slab along
-   *axis* with a *width* along the line of sight.  *p_size*
-   controls the number of pixels per particle, and *col*
-   governs the color.  *ptype* will restrict plotted
-   particles to only those that are of a given type.
-   *minimum_mass* will require that the particles be of a
-   given mass, calculated via ParticleMassMsun, to be
-   plotted.
+   Adds particle positions, based on a thick slab along ``axis`` with a
+   ``width`` along the line of sight.  ``p_size`` controls the number of pixels
+   per particle, and ``col`` governs the color.  ``ptype`` will restrict plotted
+   particles to only those that are of a given type.  ``minimum_mass`` will
+   require that the particles be of a given mass minimum mass in solar units.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("Enzo_64/DD0043/data0043")
-   p = ProjectionPlot(pf, "x", "density", center='m', width=(10, 'Mpc'))
+   import yt
+   ds = yt.load("Enzo_64/DD0043/data0043")
+   p = yt.ProjectionPlot(ds, "x", "density", center='m', width=(10, 'Mpc'))
    p.annotate_particles((10, 'Mpc'))
    p.save()
 
--------------
+Annotate a point with text
+~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 .. function:: annotate_point(self, pos, text, text_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.PointAnnotateCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.PointAnnotateCallback`.)
 
-   This adds *text* at position *pos*, where *pos* is in
-   code-space. *text_args* is a dict fed to the text
-   placement code.
+   This adds ``text`` at position ``pos``, where ``pos`` is in
+   code-space. ``text_args`` is a dict fed to the text placement code.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, 'z', 'density', center='m', width=(10, 'kpc'))
-   p.annotate_point([0.5, 0.496, 0.5], "What's going on here?", text_args={'size':'xx-large', 'color':'w'})
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.ProjectionPlot(ds, 'z', 'density', center='m', width=(10, 'kpc'))
+   p.annotate_point([0.5, 0.496, 0.5], "What's going on here?",
+                    text_args={'size':'xx-large', 'color':'w'})
    p.save()
 
--------------
+Overplot a circle on a plot
+~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_quiver(self, field_x, field_y, factor, scale=None, scale_units=None, normalize=False):
+.. function:: annotate_sphere(self, center, radius, circle_args=None, text=None,
+                              text_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.QuiverCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.SphereCallback`.)
 
-   Adds a 'quiver' plot to any plot, using the *field_x* and
-   *field_y* from the associated data, skipping every
-   *factor* datapoints *scale* is the data units per arrow
-   length unit using *scale_units*  (see
-   matplotlib.axes.Axes.quiver for more info)
+   A sphere centered at ``center`` in code units with radius ``radius`` in code
+   units will be created, with optional ``circle_args``, ``text``, and
+   ``text_args``.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, 'z', 'density', center=[0.5, 0.5, 0.5], 
-                      weight_field='density', width=(20, 'kpc'))
-   p.annotate_quiver('velocity_x', 'velocity_y', 16)
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.ProjectionPlot(ds, 'z', 'density', center='c', width=(20, 'kpc'))
+   p.annotate_sphere([0.5, 0.5, 0.5], (2, 'kpc'), {'fill':True})
    p.save()
 
--------------
+Overplot streamlines
+~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_sphere(self, center, radius, circle_args=None, text=None, text_args=None):
+.. function:: annotate_streamlines(self, field_x, field_y, factor=6.0, nx=16,
+                                   ny=16, xstart=(0, 1), ystart=(0, 1),
+                                   nsample=256, start_at_xedge=False,
+                                   start_at_yedge=False, plot_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.SphereCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.StreamlineCallback`.)
 
-   A sphere centered at *center* in code units with radius
-   *radius* in code units will be created, with optional
-   *circle_args*, *text*, and *text_args*.
+   Add streamlines to any plot, using the ``field_x`` and ``field_y`` from the
+   associated data, using ``nx`` and ``ny`` starting points that are bounded by
+   ``xstart`` and ``ystart``.  To begin streamlines from the left edge of the
+   plot, set ``start_at_xedge`` to ``True``; for the bottom edge, use
+   ``start_at_yedge``.  A line with the qmean vector magnitude will cover
+   1.0/``factor`` of the image.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, 'z', 'density', center='c', width=(20, 'kpc'))
-   p.annotate_sphere([0.5, 0.5, 0.5], (2, 'kpc'), {'fill':True})
-   p.save()
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   s = yt.SlicePlot(ds, 'z', 'density', center='c', width=(20, 'kpc'))
+   s.annotate_streamlines('velocity_x', 'velocity_y')
+   s.save()
 
--------------
+Add text
+~~~~~~~~
 
-.. function:: annotate_streamlines(self, field_x, field_y, factor=6.0, nx=16, ny=16, xstart=(0, 1), ystart=(0, 1), nsample=256, start_at_xedge=False, start_at_yedge=False, plot_args=None):
+.. function:: annotate_text(self, pos, text, data_coords=False, text_args=None):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.StreamlineCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.TextLabelCallback`.)
 
-   Add streamlines to any plot, using the *field_x* and
-   *field_y* from the associated data, using *nx* and *ny*
-   starting points that are bounded by *xstart* and
-   *ystart*.  To begin streamlines from the left edge of the
-   plot, set *start_at_xedge* to True; for the bottom edge,
-   use *start_at_yedge*.  A line with the qmean vector
-   magnitude will cover 1.0/*factor* of the image.
+   Accepts a position in (0..1, 0..1) of the image, some text and optionally
+   some text arguments. If data_coords is True, position will be in code units
+   instead of image coordinates.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   s = SlicePlot(pf, 'z', 'density', center='c', width=(20, 'kpc'))
-   s.annotate_streamlines('velocity_x', 'velocity_y')
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   s = yt.SlicePlot(ds, 'z', 'density', center='m', width=(10, 'kpc'))
+   s.annotate_text((0.5, 0.5), 'Sample text',
+                   text_args={'size':'xx-large', 'color':'w'})
    s.save()
 
--------------
+Add a title to the plot
+~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_text(self, pos, text, data_coords=False, text_args=None):
+.. function:: annotate_title(self, title='Plot'):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.TextLabelCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.TitleCallback`.)
 
-   Accepts a position in (0..1, 0..1) of the image, some
-   text and optionally some text arguments. If data_coords
-   is True, position will be in code units instead of image
-   coordinates.
+   Accepts a ``title`` and adds it to the plot.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   s = SlicePlot(pf, 'z', 'density', center='m', width=(10, 'kpc'))
-   s.annotate_text((0.5, 0.5), 'Sample text', text_args={'size':'xx-large', 'color':'w'})
-   s.save()
-
--------------
-
-.. function:: annotate_title(self, title='Plot'):
-
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.TitleCallback`.)
-
-   Accepts a *title* and adds it to the plot
-
-.. python-script::
-
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, 'z', 'density', center='c', width=(20, 'kpc'))
-   p.annotate_title('Density plot')
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.ProjectionPlot(ds, 'z', 'density', center='c', width=(20, 'kpc'))
+   p.annotate_title('Density Plot')
    p.save()
 
--------------
+Overplot quivers for the velocity field
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
-.. function:: annotate_velocity(self, factor=16, scale=None, scale_units=None, normalize=False):
+.. function:: annotate_velocity(self, factor=16, scale=None, scale_units=None,
+                                normalize=False):
 
-   (This is a proxy for :class:`~yt.visualization.plot_modifications.VelocityCallback`.)
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.VelocityCallback`.)
 
-   Adds a 'quiver' plot of velocity to the plot, skipping
-   all but every *factor* datapoint. *scale* is the data
-   units per arrow length unit using *scale_units* (see
-   matplotlib.axes.Axes.quiver for more info). if
-   *normalize* is True, the velocity fields will be scaled
-   by their local (in-plane) length, allowing morphological
-   features to be more clearly seen for fields with
-   substantial variation in field strength (normalize is not
+   Adds a 'quiver' plot of velocity to the plot, skipping all but every
+   ``factor`` datapoint. ``scale`` is the data units per arrow length unit using
+   ``scale_units`` (see matplotlib.axes.Axes.quiver for more info). if
+   ``normalize`` is ``True``, the velocity fields will be scaled by their local
+   (in-plane) length, allowing morphological features to be more clearly seen
+   for fields with substantial variation in field strength (normalize is not
    implemented and thus ignored for Cutting Planes).
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = SlicePlot(pf, 'z', 'density', center='m', width=(10, 'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.SlicePlot(ds, 'z', 'density', center='m', width=(10, 'kpc'))
    p.annotate_velocity()
    p.save()
+
+Add a Timestamp Inset Box
+~~~~~~~~~~~~~~~~~~~~~~~~~
+
+.. function:: annotate_timestamp(x, y, units=None, format="{time:.3G} {units}", 
+                                 **kwargs, normalized=False, bbox_dict=None)
+
+   (This is a proxy for
+   :class:`~yt.visualization.plot_modifications.TimestampCallback`.)
+
+   Adds the current time to the plot at point given by *x* and *y*.  If *units*
+   is given ('s', 'ms', 'ns', etc), it will covert the time to this basis.  If
+   *units* is None, it will attempt to figure out the correct value by which to
+   scale.  The *format* keyword is a template string that will be evaluated and
+   displayed on the plot.  If *normalized* is true, *x* and *y* are interpreted
+   as normalized plot coordinates (0,0 is lower-left and 1,1 is upper-right)
+   otherwise *x* and *y* are assumed to be in plot coordinates. The *bbox_dict*
+   is an optional dict of arguments for the bbox that frames the timestamp, see
+   matplotlib's text annotation guide for more details. All other *kwargs* will
+   be passed to the text() method on the plot axes.  See matplotlib's text()
+   functions for more information.
+
+.. python-script::
+
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = yt.SlicePlot(ds, 'z', 'density', center='c', width=(20, 'kpc'))
+   p.annotate_timestamp()
+   p.save()

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/visualizing/manual_plotting.rst
--- a/doc/source/visualizing/manual_plotting.rst
+++ b/doc/source/visualizing/manual_plotting.rst
@@ -35,11 +35,12 @@
 .. python-script::
    
    import pylab as P
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   import numpy as np
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
 
-   c = pf.h.find_max('density')[1]
-   proj = pf.proj('density', 0)
+   c = ds.find_max('density')[1]
+   proj = ds.proj('density', 0)
 
    width = (10, 'kpc') # we want a 1.5 mpc view
    res = [1000, 1000] # create an image with 1000x1000 pixels
@@ -64,22 +65,33 @@
 Line Plots
 ----------
 
-This is perhaps the simplest thing to do. ``yt`` provides a number of one dimensional objects, and these return a 1-D numpy array of their contents with direct dictionary access. As a simple example, take a :class:`~yt.data_objects.data_containers.AMROrthoRayBase` object, which can be created from a index by calling ``pf.ortho_ray(axis, center)``. 
+This is perhaps the simplest thing to do. ``yt`` provides a number of one
+dimensional objects, and these return a 1-D numpy array of their contents with
+direct dictionary access. As a simple example, take a
+:class:`~yt.data_objects.data_containers.AMROrthoRayBase` object, which can be
+created from a index by calling ``pf.ortho_ray(axis, center)``.
 
 .. python-script::
 
-   from yt.mods import *
+   import yt
+   import numpy as np
    import pylab as P
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   c = pf.h.find_max("density")[1]
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   c = ds.find_max("density")[1]
    ax = 0 # take a line cut along the x axis
-   ray = pf.ortho_ray(ax, (c[1], c[2])) # cutting through the y0,z0 such that we hit the max density
+
+   # cutting through the y0,z0 such that we hit the max density
+   ray = ds.ortho_ray(ax, (c[1], c[2]))
+
+   # Sort the ray values by 'x' so there are no discontinuities
+   # in the line plot
+   srt = np.argsort(ray['x'])
 
    P.subplot(211)
-   P.semilogy(np.array(ray['x']), np.array(ray['density']))
+   P.semilogy(np.array(ray['x'][srt]), np.array(ray['density'][srt]))
    P.ylabel('density')
    P.subplot(212)
-   P.semilogy(np.array(ray['x']), np.array(ray['temperature']))
+   P.semilogy(np.array(ray['x'][srt]), np.array(ray['temperature'][srt]))
    P.xlabel('x')
    P.ylabel('temperature')
 

diff -r 63f99967988f131df43d39ddb3b809b9f88b8312 -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -25,10 +25,10 @@
 If you need to take a quick look at a single simulation output, ``yt``
 provides the ``PlotWindow`` interface for generating annotated 2D
 visualizations of simulation data.  You can create a ``PlotWindow`` plot by
-supplying a parameter file, a list of fields to plot, and a plot center to
-create a :class:`~yt.visualization.plot_window.SlicePlot`,
+supplying a dataset, a list of fields to plot, and a plot center to
+create a :class:`~yt.visualization.plot_window.AxisAlignedSlicePlot`,
 :class:`~yt.visualization.plot_window.ProjectionPlot`, or
-:class:`~yt.visualization.plot_window.OffAxisSlicePlot`.
+:class:`~yt.visualization.plot_window.OffAxisProjectionPlot`.
 
 Plot objects use ``yt`` data objects to extract the maximum resolution
 data available to render a 2D image of a field. Whenever a
@@ -37,7 +37,8 @@
 is requested of it -- for instance, when the width or field is changed
 -- this high-resolution data is then pixelized and placed in a buffer
 of fixed size. This is accomplished behind the scenes using
-:class:`~yt.visualization.fixed_resolution.FixedResolutionBuffer`
+:class:`~yt.visualization.fixed_resolution.FixedResolutionBuffer`.
+
 ``PlotWindow`` expose the underlying matplotlib ``figure`` and
 ``axes`` objects, making it easy to customize your plots and 
 add new annotations.
@@ -45,28 +46,33 @@
 .. _slice-plots:
 
 Slice Plots
------------
+~~~~~~~~~~~
 
-The quickest way to plot a slice of a field through your data is to use
-:class:`~yt.visualization.plot_window.SlicePlot`.  Say we want to visualize a
-slice through the Density field along the z-axis centered on the center of the
-simulation box in a simulation dataset we've opened and stored in the parameter
-file object ``pf``.  This can be accomplished with the following command:
+The quickest way to plot a slice of a field through your data is via
+:class:`~yt.visualization.plot_window.SlicePlot`.  These plots are generally
+quicker than projections because they only need to read and process a slice
+through the dataset.
+
+The following script plots a slice through the density field along the z-axis
+centered on the center of the simulation box in a simulation dataset we've
+opened and stored in ``ds``:
 
 .. code-block:: python
 
-   >>> slc = SlicePlot(pf, 'z', 'density')
+   >>> slc = yt.SlicePlot(ds, 'z', 'density')
    >>> slc.save()
 
 These two commands will create a slice object and store it in a variable we've
-called ``slc``.  We then call the ``save()`` function that is associated with
-the slice object.  This automatically saves the plot in png image format with an
-automatically generated filename.  If you don't want the slice object to stick
-around, you can accomplish the same thing in one line:
+called ``slc``.  Since this plot is aligned with the simulation coordinate
+system, ``slc`` is an instance of
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot`. We then call the
+``save()`` function, which automatically saves the plot in png image format with
+an automatically generated filename.  If you don't want the slice object to
+stick around, you can accomplish the same thing in one line:
 
 .. code-block:: python
    
-   >>> SlicePlot(pf, 'z', 'density').save()
+   >>> yt.SlicePlot(ds, 'z', 'density').save()
 
 It's nice to keep the slice object around if you want to modify the plot.  By
 default, the plot width will be set to the size of the simulation box.  To zoom
@@ -75,41 +81,58 @@
 
 .. code-block:: python
 
-   >>> slc = SlicePlot(pf, 'z', 'density')
+   >>> slc = yt.SlicePlot(ds, 'z', 'density')
    >>> slc.zoom(10)
    >>> slc.save('zoom')
 
 This will save a new plot to disk with a different filename - prepended with
-'zoom' instead of the name of the parameter file. If you want to set the width
+'zoom' instead of the name of the dataset. If you want to set the width
 manually, you can do that as well. For example, the following sequence of
 commands will create a slice, set the width of the plot to 10 kiloparsecs, and
 save it to disk.
 
 .. code-block:: python
 
-   >>> slc = SlicePlot(pf, 'z', 'density')
-   >>> slc.set_width((10,'kpc'))
+   >>> from yt.units import kpc
+   >>> slc = yt.SlicePlot(ds, 'z', 'density')
+   >>> slc.set_width(10*kpc)
    >>> slc.save('10kpc')
 
-The SlicePlot also optionally accepts the coordinate to center the plot on and
-the width of the plot:
+The plot width can be specified independently along the x and y direction by
+passing a tuple of widths.  An individual width can also be represented using a
+``(value, unit)`` tuple.  The following sequence of commands all equivalently
+set the width of the plot to 200 kiloparsecs in the ``x`` and ``y`` direction.
 
 .. code-block:: python
 
-   >>> SlicePlot(pf, 'z', 'density', center=[0.2, 0.3, 0.8], 
-   ...           width = (10,'kpc')).save()
+   >>> from yt.units import kpc
+   >>> slc.set_width(200*kpc)
+   >>> slc.set_width((200, 'kpc'))
+   >>> slc.set_width((200*kpc, 200*kpc))
 
-The center must be given in code units.  Optionally, you can supply 'c' or 'm'
-for the center.  These two choices will center the plot on the center of the
-simulation box and the coordinate of the maximum density cell, respectively.
+The ``SlicePlot`` also optionally accepts the coordinate to center the plot on
+and the width of the plot:
+
+.. code-block:: python
+
+   >>> yt.SlicePlot(ds, 'z', 'density', center=[0.2, 0.3, 0.8],
+   ...              width = (10,'kpc')).save()
+
+The plot center is relative to the simulation coordinate system.  If supplied
+without units, the center is assumed by in code units.  Optionally, you can
+supply 'c' or 'm' for the center.  These two choices will center the plot on the
+center of the simulation box and the coordinate of the maximum density cell,
+respectively.
 
 Here is an example that combines all of the options we just discussed.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', center=[0.5, 0.5, 0.5], width=(20,'kpc'))
+   import yt
+   from yt.units import kpc
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', center=[0.5, 0.5, 0.5],
+                      width=(20,'kpc'))
    slc.save()
 
 The above example will display an annotated plot of a slice of the
@@ -118,14 +141,14 @@
 letter 'z', corresponding to the z-axis.  Finally, the image is saved to
 a png file.
 
-Conceptually, you can think of the SlicePlot as an adjustable window
+Conceptually, you can think of the plot object as an adjustable window
 into the data. For example:
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'pressure', center='c')
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'pressure', center='c')
    slc.save()
    slc.zoom(30)
    slc.save('zoom')
@@ -138,32 +161,43 @@
 interesting region in the simulation and adjust the boundaries of the
 region to visualize on the fly.
 
-A slice object can also add annotations like a title, an overlying
-quiver plot, the location of grid boundaries, halo-finder annotations,
-and many other annotations, including user-customizable annotations.
-For example:
+See :class:`~yt.visualization.plot_window.AxisAlignedSlicePlot` for the 
+full class description.
+
+.. _off-axis-slices:
+
+Off Axis Slices
+~~~~~~~~~~~~~~~
+
+Off axis slice plots can be generated in much the same way as
+grid-aligned slices.  Off axis slices use
+:class:`~yt.data_objects.data_containers.AMRCuttingPlaneBase` to slice
+through simulation domains at an arbitrary oblique angle.  A
+:class:`~yt.visualization.plot_window.OffAxisSlicePlot` can be
+instantiated by specifying a dataset, the normal to the cutting
+plane, and the name of the fields to plot.  Just like an
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot`, an
+``OffAxisSlicePlot`` can be created via the
+:class:`~yt.visualization.plot_window.SlicePlot` function. For example:
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
-   slc.annotate_grids()
-   slc.save()
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   L = [1,1,0] # vector normal to cutting plane
+   north_vector = [-1,1,0]
+   cut = yt.SlicePlot(ds, L, 'density', width=(25, 'kpc'),
+                      north_vector=north_vector)
+   cut.save()
 
-will plot the density field in a 10 kiloparsec slice through the
-z-axis centered on the highest density point in the simulation domain.
-Before saving the plot, the script annotates it with the grid
-boundaries, which are drawn as thick black lines by default.
-
-Annotations are described in :ref:`callbacks`.  See
-:class:`~yt.visualization.plot_window.SlicePlot` for the full class
-description.
+In this case, a normal vector for the cutting plane is supplied in the second
+argument. Optionally, a `north_vector` can be specified to fix the orientation
+of the image plane.
 
 .. _projection-plots:
 
 Projection Plots
-----------------
+~~~~~~~~~~~~~~~~
 
 Using a fast adaptive projection, ``yt`` is able to quickly project
 simulation data along the coordinate axes.
@@ -174,15 +208,15 @@
 
 .. python-script::
  
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   prj = ProjectionPlot(pf, 2, 'density', width=(25, 'kpc'), 
-                        weight_field=None)
+   import yt
+   from yt.units import kpc
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   prj = yt.ProjectionPlot(ds, 2, 'temperature', width=25*kpc,
+                           weight_field='density')
    prj.save()
 
-will create a projection of Density field along the x axis, plot it,
-and then save it to a png image file.  The projection is only carried
-out to level 2 of the AMR index and no weighting is applied.
+will create a density-weighted projection of the temperature field along the x
+axis, plot it, and then save the plot to a png image file.
 
 Like :ref:`slice-plots`, annotations and modifications can be applied
 after creating the ``ProjectionPlot`` object.  Annotations are
@@ -190,43 +224,8 @@
 :class:`~yt.visualization.plot_window.ProjectionPlot` for the full
 class description.
 
-.. _off-axis-slices:
-
-Off Axis Slice Plots
---------------------
-
-Off axis slice plots can be generated in much the same way as
-grid-aligned slices.  Off axis slices use
-:class:`~yt.data_objects.data_containers.AMRCuttingPlaneBase` to slice
-through simulation domains at an arbitrary oblique angle.  A
-:class:`~yt.visualization.plot_window.OffAxisSlicePlot` can be
-instantiated by specifying a parameter file, the normal to the cutting
-plane, and the name of the fields to plot.  For example:
-
-.. python-script::
-
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   L = [1,1,0] # vector normal to cutting plane
-   north_vector = [-1,1,0]
-   cut = OffAxisSlicePlot(pf, L, 'density', width=(25, 'kpc'), 
-                          north_vector=north_vector)
-   cut.save()
-
-creates an off-axis slice in the plane perpendicular to ``L``,
-oriented such that ``north_vector`` is the up direction.  If ``L`` and
-``north_vector`` are not perpendicular, the component of
-``north_vector`` perpendicular to ``L`` is used. Like
-:ref:`slice-plots`, annotations and modifications can be applied after
-creating the ``OffAxisSlicePlot`` object.  Annotations are described
-in :ref:`callbacks`.  See
-:class:`~yt.visualization.plot_window.OffAxisSlicePlot` for the full
-class description.
-
-.. _off-axis-projections:
-
 Off Axis Projection Plots
--------------------------
+~~~~~~~~~~~~~~~~~~~~~~~~~
 
 Off axis projection plots .  Internally, off axis projections are
 created using :ref:`the-camera-interface` by applying the
@@ -246,15 +245,16 @@
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   import yt
+   import numpy as np
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
    L = [1,1,0] # vector normal to cutting plane
    north_vector = [-1,1,0]
    W = [0.02, 0.02, 0.02]
    c = [0.5, 0.5, 0.5]
    N = 512
-   image = off_axis_projection(pf, c, L, W, N, "density")
-   write_image(np.log10(image), "%s_offaxis_projection.png" % pf)
+   image = yt.off_axis_projection(ds, c, L, W, N, "density")
+   yt.write_image(np.log10(image), "%s_offaxis_projection.png" % ds)
 
 Here, ``W`` is the width of the projection in the x, y, *and* z
 directions.
@@ -268,32 +268,30 @@
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
    L = [1,1,0] # vector normal to cutting plane
    north_vector = [-1,1,0]
-   prj = OffAxisProjectionPlot(pf,L,'density',width=(25, 'kpc'), 
-                               north_vector=north_vector)
+   prj = yt.OffAxisProjectionPlot(ds,L,'density',width=(25, 'kpc'),
+                                  north_vector=north_vector)
    prj.save()
 
 OffAxisProjectionPlots can also be created with a number of
-keyword arguments, as described in the `api reference`__ for the
-class initializer.
-
-__ :class:`~yt.visualization.plot_window.OffAxisProjectionPlot`
+keyword arguments, as described in
+:class:`~yt.visualization.plot_window.OffAxisProjectionPlot`
 
 Plot Customization
 ------------------
 
 You can customize each of the four plot types above in identical ways.  We'll go
-over each of the customizations methos below.  For each of the examples below we
+over each of the customizations methods below.  For each of the examples below we
 will modify the following plot.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.save()
 
 Panning and zooming
@@ -301,78 +299,84 @@
 
 There are three methods to dynamically pan around the data.  
 
-:class:`~yt.visualization.plot_window.SlicePlot.pan` accepts x and y deltas in code
-units.
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.pan` accepts x and y
+deltas.
 
 .. python-script::
 
-   from yt.mods import *
+   import yt
    from yt.units import kpc
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.pan((2*kpc, 2*kpc))
    slc.save()
 
-:class:`~yt.visualization.plot_window.SlicePlot.pan_rel` accepts deltas in units relative
-to the field of view of the plot.  
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.pan_rel` accepts deltas 
+in units relative to the field of view of the plot.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.pan_rel((0.1, -0.1))
    slc.save()
 
-:class:`~yt.visualization.plot_window.SlicePlot.zoom` accepts a factor to zoom in by.
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.zoom` accepts a factor to zoom in by.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.zoom(2)
    slc.save()
 
 Set axes units
 ~~~~~~~~~~~~~~
 
-:class:`~yt.visualization.plot_window.SlicePlot.set_axes_unit` allows the customization of
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_axes_unit` allows the customization of
 the axes unit labels.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.set_axes_unit('Mpc')
    slc.save()
 
+The same result could have been accomplished by explicitly setting the ``width``
+to ``(.01, 'Mpc')``.
+
 Set the plot center
 ~~~~~~~~~~~~~~~~~~~
 
-The :class:`~yt.visualization.plot_window.SlicePlot.set_center` function accepts a new
-center for the plot, in code units.  New centers must be two element tuples.
+The :class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_center`
+function accepts a new center for the plot, in code units.  New centers must be
+two element tuples.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
-   slc.set_center((0.5, 0.5))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
+   slc.set_center((0.5, 0.503))
    slc.save()
 
 Fonts
 ~~~~~
 
-:class:`~yt.visualization.plot_window.SlicePlot.set_font` allows font costomization.
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_font` allows font
+costomization.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
-   slc.set_font({'family': 'sans-serif', 'style': 'italic','weight': 'bold', 'size': 24})
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
+   slc.set_font({'family': 'sans-serif', 'style': 'italic',
+                 'weight': 'bold', 'size': 24})
    slc.save()
 
 Colormaps
@@ -383,117 +387,173 @@
 different fields tracked by the plot object.
 
 To change the colormap for the plot, call the
-:class:`~yt.visualization.plot_window.SlicePlot.set_cmap` function.  Use any of the
-colormaps listed in the :ref:`colormaps` section.
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_cmap` function.
+Use any of the colormaps listed in the :ref:`colormaps` section.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.set_cmap('density', 'RdBu_r')
    slc.save()
 
-The :class:`~yt.visualization.plot_window.SlicePlot.set_log` function accepts a field name
-and a boolean.  If the boolean is :code:`True`, the colormap for the field will
-be log scaled.  If it is `False` the colormap will be linear.
+The :class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_log` function
+accepts a field name and a boolean.  If the boolean is ``True``, the colormap
+for the field will be log scaled.  If it is ``False`` the colormap will be
+linear.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.set_log('density', False)
    slc.save()
 
-Lastly, the :class:`~yt.visualization.plot_window.SlicePlot.set_zlim` function makes it
-possible to set a custom colormap range.
+Lastly, the :class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_zlim`
+function makes it possible to set a custom colormap range.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.set_zlim('density', 1e-30, 1e-25)
    slc.save()
 
+Annotations
+~~~~~~~~~~~
+
+A slice object can also add annotations like a title, an overlying
+quiver plot, the location of grid boundaries, halo-finder annotations,
+and many other annotations, including user-customizable annotations.
+For example:
+
+.. python-script::
+
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
+   slc.annotate_grids()
+   slc.save()
+
+will plot the density field in a 10 kiloparsec slice through the
+z-axis centered on the highest density point in the simulation domain.
+Before saving the plot, the script annotates it with the grid
+boundaries, which are drawn as thick black lines by default.
+
+Annotations are described in :ref:`callbacks`.
+
 Set the size of the plot
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
 To set the size of the plot, use the
-:class:`~yt.visualization.plot_window.SlicePlot.set_window_size` function.  The argument
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_figure_size` function.  The argument
 is the size of the longest edge of the plot in inches.  View the full resolution
 image to see the difference more clearly.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
-   slc.set_window_size(10)
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
+   slc.set_figure_size(10)
    slc.save()
 
 To change the resolution of the image, call the
-:class:`~yt.visualization.plot_window.SlicePlot.set_buff_size` function.
+:class:`~yt.visualization.plot_window.AxisAlignedSlicePlot.set_buff_size` function.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   slc = SlicePlot(pf, 'z', 'density', width=(10,'kpc'))
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   slc = yt.SlicePlot(ds, 'z', 'density', width=(10,'kpc'))
    slc.set_buff_size(1600)
    slc.save()
 
+Further customization via matplotlib
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Each ``PlotWindow`` object is really a container for plots - one plot for each
+field specified in the list of fields supplied when the plot object is
+created. The individual plots can be accessed via the ``plots`` dictionary
+attached to each ``PlotWindow`` object:
+
+.. code-block:: python
+
+   >>> slc = SlicePlot(ds, 2, ['density', 'temperature']
+   >>> dens_plot = slc.plots['density']
+
+In this example ``dens_plot`` is an instance of
+:class:`~yt.visualization.plot_window.WindowPlotMPL`, an object that wraps the
+matplotlib ``figure`` and ``axes`` objects.  We can access these matplotlib primitives via attributes of ``dens_plot``.
+
+.. code-block:: python
+
+   >>> figure = dens_plot.figure
+   >>> axes = dens_plot.axes
+   >>> colorbar_axes = dens_plot.cax
+
+These are the :matplotlib:class:`figure`, and :matplotlib:class:`axes` objects
+that control the actual drawing of the plot.  Arbitrary plot customizations
+are possible by manipulating these objects.  See :ref:`matplotlib-primitives` for
+an example.
+
 .. _how-to-make-1d-profiles:
 
 1D Profile Plots
 ----------------
 
-1D profiles are used to calculated the average or the sum of a given quantity
-with respect to a second quantity.  This means the "average density as a
-function of radius" or "the total mass within a given set of density bins."
+1D profiles are used to calculate the average or the sum of a given quantity
+with respect to a second quantity.  Two common examples are the "average density
+as a function of radius" or "the total mass within a given set of density bins."
 When created, they default to the average: in fact, they default to the average
 as weighted by the total cell mass.  However, this can be modified to take
 either the total value or the average with respect to a different quantity.
 
-Profiles operate on data objects; they will take the entire data contained in a
-sphere, a prism, an extracted region and so on, and they will calculate and use
-that as input to their calculation.  To make a 1D profile plot, create a
-(:class:`~yt.visualization.profile_plotter.ProfilePlot`) object, supplying the 
-data object, the field for binning, and a list of fields to be profiled.
+Profiles operate on :ref:`data objects <using-objects>`; they will take the
+entire data contained in a sphere, a prism, an extracted region and so on, and
+they will calculate and use that as input to their calculation.  To make a 1D
+profile plot, create a (:class:`~yt.visualization.profile_plotter.ProfilePlot`)
+object, supplying the data object, the field for binning, and a list of fields
+to be profiled.
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   my_galaxy = pf.disk([0.5, 0.5, 0.5], [0.0, 0.0, 1.0], 0.01, 0.003)
-   plot = ProfilePlot(my_galaxy, "density", ["temperature"])
+   import yt
+   from yt.units import kpc
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   my_galaxy = ds.disk(ds.domain_center, [0.0, 0.0, 1.0], 10*kpc, 3*kpc)
+   plot = yt.ProfilePlot(my_galaxy, "density", ["temperature"])
    plot.save()
 
 This will create a :class:`yt.data_objects.data_containers.AMRCylinderBase`
-centered at [0.3, 0.5, 0.8], with a normal vector of [0.4, 0.5, 0.1], radius of
-0.01 and height of 0.001 and will then make a plot of the average (as a 
-function of the cell mass) temperature as a function of density.
+centered at [0.5, 0.5, 0.5], with a normal vector of [0.0, 0.0, 1.0], radius of
+10 kiloparsecs and height of 3 kiloparsecs and will then make a plot of the
+mass-weighted average temperature as a function of density for all of the gas
+contained in the cylinder.
 
-As another example, we create a sphere of radius 100 pc and plot total mass 
-in every equally-spaced temperature bin/
-
-We could also have allowed the plot collection to create a sphere for us, as
-well.  For instance:
+We could also have made a profile considering only the gas in a sphere.
+For instance:
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   my_sphere = pf.sphere([0.5, 0.5, 0.5], (100, "kpc"))
-   plot = ProfilePlot(my_sphere, "temperature", ["cell_mass"],
-                      weight_field=None)
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   my_sphere = ds.sphere([0.5, 0.5, 0.5], (100, "kpc"))
+   plot = yt.ProfilePlot(my_sphere, "temperature", ["cell_mass"],
+                         weight_field=None)
    plot.save()
 
-Note that because we have specified the weighting field to be none, it operates 
-as a local-bin accumulator.  We can also accumulate along the x-axis by setting 
-the **accumulation** keyword argument to True, which is useful for plots of 
-enclosed mass.
+Note that because we have specified the weighting field to be none, it operates
+the profile plot will display the accumulated cell mass as a function of
+temperature rather than the average.  We can also accumulate along the x-axis by
+setting the **accumulation** keyword argument to True, which is useful for plots
+of enclosed mass.
+
+Also note the use of a ``(value, unit)`` tuple. These can be used interchangably
+with units explicitly imported from ``yt.units``.
 
 You can also access the data generated by profiles directly, which can be
 useful for overplotting average quantities on top of phase plots, or for
@@ -506,32 +566,30 @@
 
    plot = ProfilePlot(my_sphere, "temperature", ["cell_mass"],
                       weight_field=None)
-   # print the x field
+   profile = plot.profiles[0]
+   # print the bin field, in this case temperature
    print plot.profiles[-1].x
-   # print the profiled temperature field
-   print plot.profiles[-1].field_data["temperature"]
+   # print the profiled cell_mass field
+   print plot.profiles[-1]["cell_mass"]
 
-Other options, such as the number of bins, are also configurable. See the 
-documentation for 
-The number of bins and other options and tweaks are 
-available for these methods.  See the documentation for 
-:class:`~yt.visualization.profile_plotter.ProfilePlot`
-for more information.
+Other options, such as the number of bins, are also configurable. See the
+documentation for :class:`~yt.visualization.profile_plotter.ProfilePlot` for
+more information.
 
 Overplotting Multiple 1D Profiles
 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 It is often desirable to overplot multiple 1D profile to show evolution 
 with time.  This is supported with the ``from_profiles`` class method.  
-1D profiles are created with the :meth:`yt.data_objects.profiles.create_profile` 
+1D profiles are created with the :func:`yt.data_objects.profiles.create_profile` 
 method and then given to the ProfilePlot object.
 
 .. python-script::
 
-   from yt.mods import *
+   import yt
 
    # Create a time-series object.
-   es = simulation("enzo_tiny_cosmology/32Mpc_32.enzo", "Enzo")
+   es = yt.simulation("enzo_tiny_cosmology/32Mpc_32.enzo", "Enzo")
    es.get_time_series(redshifts=[5, 4, 3, 2, 1, 0])
 
 
@@ -540,23 +598,114 @@
    labels = []
 
    # Loop over each dataset in the time-series.
-   for pf in es:
+   for ds in es:
        # Create a data container to hold the whole dataset.
-       ad = pf.h.all_data()
+       ad = ds.all_data()
        # Create a 1d profile of density vs. temperature.
-       profiles.append(create_profile(ad, ["temperature"], 
-                                      fields=["cell_mass"],
-                                      weight_field=None,
-                                      accumulation=True))
+       profiles.append(yt.create_profile(ad, ["temperature"], 
+                                         fields=["cell_mass"],
+                                         weight_field=None,
+                                         accumulation=True))
        # Add labels
-       labels.append("z = %.2f" % pf.current_redshift)
+       labels.append("z = %.2f" % ds.current_redshift)
 
    # Create the profile plot from the list of profiles.
-   plot = ProfilePlot.from_profiles(profiles, labels=labels)
+   plot = yt.ProfilePlot.from_profiles(profiles, labels=labels)
 
    # Save the image.
    plot.save()
 
+Customizing axis limits
+~~~~~~~~~~~~~~~~~~~~~~~
+
+By default the x and y limits for ``ProfilePlot`` are determined using the
+:class:`~yt.data_objects.derived_quantities.Extrema` derived quantity.  If you
+want to create a plot with custom axis limits, you have two options.
+
+First, you can create a custom profile object using
+:func:`~yt.data_objects.profiles.create_profile`.  This function accepts a dictionary of ``(max, min)`` tuples keyed to field names.
+
+.. python-script::
+
+    import yt
+    import yt.units as u
+    ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+    sp = ds.sphere('m', 10*u.kpc)
+    profiles = yt.create_profile(sp, "temperature", "density",
+                                 weight_field=None, 
+                                 extrema={'temperature': (1e3, 1e7),
+                                          'density': (1e-26, 1e-22)})
+    plot = yt.ProfilePlot.from_profiles(profiles)
+    plot.save()
+
+You can also make use of the
+:meth:`yt.visualization.profile_plotter.ProfilePlot.set_xlim` and
+:meth:`yt.visualization.profile_plotter.ProfilePlot.set_ylim` functions to
+customize the axes limits of a plot that has already been created.  Note that
+calling ``set_xlim`` is much slower than calling ``set_ylim``.  This is because
+```set_xlim`` must recreate the profile object using the specified extrema.
+Creating a profile directly via ``create_profile`` might be significant faster.
+If you find that this operation is slow, consider creating your profile via
+``create_profile``.  Note that since there is only one bin field, ``set_xlim``
+does not accept a field name as the first argument.
+
+.. python-script::
+
+   import yt
+   import yt.units as u
+   ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+   sp = ds.sphere('m', 10*u.kpc)
+   plot = yt.ProfilePlot(sp, "temperature", "density", weight_field=None)
+   plot.set_xlim(1e3, 1e7)
+   plot.set_ylim("density", 1e-26, 1e-22)
+   plot.save()
+
+
+Customizing Units
+~~~~~~~~~~~~~~~~~
+
+Units for both the x and y axis can be controlled via the
+:meth:`~yt.visualization.profile_plotter.ProfilePlot.set_unit` method.
+Adjusting the plot units does not require recreating the histogram, so adjusting
+units will always be inexpensive, requiring only an in-place unit conversion.
+
+In the following example we create a a plot of the average density in solar
+masses per cubic parsec as a function of radius in kiloparsecs.
+
+.. python-script::
+
+    import yt
+    import yt.units as u
+    ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+    sp = ds.sphere('m', 10*u.kpc)
+    plot = yt.ProfilePlot(sp, "radius", "density", weight_field=None)
+    plot.set_unit("density", "msun/pc**3")
+    plot.set_unit("radius", "kpc")
+    plot.save()
+
+Linear and Logarithmic Scaling
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+The axis scaling can be manipulated via the
+:meth:`~yt.visualization.profile_plotter.ProfilePlot.set_log` function.  This
+function accepts a field name and a boolean.  If the boolean is ``True``, the
+field is plotted in log scale.  If ``False``, the field is plotted in linear
+scale.
+
+In the following example we create a plot of the average x velocity as a
+function of radius.  Since the x component of the velocity vector can be
+negative, we set the scaling to be linear for this field.
+
+.. python-script::
+
+   import yt
+   import yt.units as u
+   ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+   sp = ds.sphere('m', 10*u.kpc)
+   plot = yt.ProfilePlot(sp, "radius", "x-velocity", weight_field=None)
+   plot.set_log("x-velocity", False)
+   plot.save()
+
 Altering Line Properties
 ~~~~~~~~~~~~~~~~~~~~~~~~
 
@@ -581,47 +730,72 @@
 2D Phase Plots
 --------------
 
-2D phase plots function in much the same was as 1D phase plots, but with a 
-:class:`~yt.visualization.profile_plotter.PhasePlot` object.  Much like 1D profiles, 
-2D profiles (phase plots) are best thought of as plotting a distribution of points, 
-either taking the average or the accumulation in a bin.  For example, to generate a 
-2D distribution of mass enclosed in density and temperature bins, you can do:
+2D phase plots function in much the same was as 1D phase plots, but with a
+:class:`~yt.visualization.profile_plotter.PhasePlot` object.  Much like 1D
+profiles, 2D profiles (phase plots) are best thought of as plotting a
+distribution of points, either taking the average or the accumulation in a bin.
+For example, to generate a 2D distribution of mass enclosed in density and
+temperature bins, you can do:
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   my_sphere = pf.sphere("c", (50, "kpc"))
-   plot = PhasePlot(my_sphere, "density", "temperature", ["cell_mass"],
-                    weight_field=None)
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   my_sphere = ds.sphere("c", (50, "kpc"))
+   plot = yt.PhasePlot(my_sphere, "density", "temperature", ["cell_mass"],
+                       weight_field=None)
    plot.save()
 
 If you would rather see the average value of a field as a function of two other
-fields, you can neglect supplying the *weight* parameter.  This would look
+fields, you can set the ``weight_field`` parameter to ``None``.  This would look
 something like:
 
 .. python-script::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   my_sphere = pf.sphere("c", (50, "kpc"))
-   plot = PhasePlot(my_sphere, "density", "temperature", ["H_fraction"],
-                    weight_field="cell_mass")
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   my_sphere = ds.sphere("c", (50, "kpc"))
+   plot = yt.PhasePlot(my_sphere, "density", "temperature", ["H_fraction"],
+                       weight_field=None)
+   plot.save()
+
+Customizing Phase Plots
+~~~~~~~~~~~~~~~~~~~~~~~
+
+Similarly to 1D profile plots, ``PhasePlot`` can be customized via ``set_unit``,
+``set_xlim``, ``set_ylim``, and ``set_zlim``.  The following example illustrates
+how to manipulate these functions.
+
+.. python-script::
+
+   import yt
+   ds = yt.load("sizmbhloz-clref04SNth-rs9_a0.9011/sizmbhloz-clref04SNth-rs9_a0.9011.art")
+   center = ds.arr([64.0, 64.0, 64.0], 'code_length')
+   rvir = ds.quan(1e-1, "Mpccm/h")
+
+   sph = ds.sphere(center, rvir)
+   plot = yt.PhasePlot(sph, "density", "temperature", "cell_mass",
+                       weight_field=None)
+   plot.set_unit('density', 'Msun/pc**3')
+   plot.set_unit('cell_mass', 'Msun')
+   plot.set_xlim(1e-5,1e1)
+   plot.set_ylim(1,1e7)
    plot.save()
 
 Probability Distribution Functions and Accumulation
 ---------------------------------------------------
 
-Both 1D and 2D profiles which show the total of amount of some field, such as mass, 
-in a bin (done by setting the **weight_field** keyword to None) can be turned into 
-probability distribution functions (PDFs) by setting the **fractional** keyword to 
-True.  When set to True, the value in each bin is divided by the sum total from all 
-bins.  These can be turned into cumulative distribution functions (CDFs) by setting 
-the **accumulation** keyword to True.  This will make is so that the value in any bin 
-N is the cumulative sum of all bins from 0 to N.  The direction of the summation can be 
-rversed by setting **accumulation** to -True.  For PhasePlots, the accumulation can be 
-set independently for each axis by setting **accumulation** to a list of True/-True/False 
-values.
+Both 1D and 2D profiles which show the total of amount of some field, such as
+mass, in a bin (done by setting the ``weight_field`` keyword to ``None``) can be
+turned into probability distribution functions (PDFs) by setting the
+``fractional`` keyword to ``True``.  When set to ``True``, the value in each bin
+is divided by the sum total from all bins.  These can be turned into cumulative
+distribution functions (CDFs) by setting the ``accumulation`` keyword to
+``True``.  This will make is so that the value in any bin N is the cumulative
+sum of all bins from 0 to N.  The direction of the summation can be reversed by
+setting ``accumulation`` to ``-True``.  For ``PhasePlot``, the accumulation can
+be set independently for each axis by setting ``accumulation`` to a list of
+``True``/ ``-True`` /``False`` values.
 
 .. _interactive-plotting:
 
@@ -646,9 +820,9 @@
 
 .. notebook-cell::
 
-   from yt.mods import *
-   pf = load("IsolatedGalaxy/galaxy0030/galaxy0030")
-   p = ProjectionPlot(pf, "x", "density", center='m', width=(10,'kpc'),
+   import yt
+   ds = yt.load("IsolatedGalaxy/galaxy0030/galaxy0030")
+   p = ProjectionPlot(ds, "x", "density", center='m', width=(10,'kpc'),
                       weight_field='density')
    p.show()
 
@@ -682,7 +856,7 @@
 .. code-block:: python
 
    >>> import yt.visualization.eps_writer as eps
-   >>> slc = SlicePlot(pf, 'z', 'density')
+   >>> slc = yt.SlicePlot(ds, 'z', 'density')
    >>> slc.set_width(25, 'kpc')
    >>> eps_fig = eps.single_plot(slc)
    >>> eps_fig.save_fig('zoom', format='eps')
@@ -706,9 +880,11 @@
 
 .. code-block:: python
 
+   >>> import yt
    >>> import yt.visualization.eps_writer as eps
-   >>> slc = SlicePlot(pf, 'z', ['density', 'temperature', 'Pressure',
-                       'VelocityMagnitude'])
+   >>>
+   >>> slc = yt.SlicePlot(ds, 'z', ['density', 'temperature', 'Pressure',
+                          'VelocityMagnitude'])
    >>> slc.set_width(25, 'kpc')
    >>> eps_fig = eps.multiplot_yt(2, 2, slc, bare_axes=True)
    >>> eps_fig.scale_line(0.2, '5 kpc')

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

https://bitbucket.org/yt_analysis/yt/commits/d7567af29272/
Changeset:   d7567af29272
Branch:      yt-3.0
User:        ngoldbaum
Date:        2014-07-13 23:25:38
Summary:     Adding docs for PhasePlot.from_profile().  Fixing bugs found after adding example.
Affected #:  3 files

diff -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced -r d7567af2927271ee6d4c5366bc8920b93bac161e doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -772,8 +772,8 @@
    ds = yt.load("sizmbhloz-clref04SNth-rs9_a0.9011/sizmbhloz-clref04SNth-rs9_a0.9011.art")
    center = ds.arr([64.0, 64.0, 64.0], 'code_length')
    rvir = ds.quan(1e-1, "Mpccm/h")
+   sph = ds.sphere(center, rvir)
 
-   sph = ds.sphere(center, rvir)
    plot = yt.PhasePlot(sph, "density", "temperature", "cell_mass",
                        weight_field=None)
    plot.set_unit('density', 'Msun/pc**3')
@@ -782,6 +782,29 @@
    plot.set_ylim(1,1e7)
    plot.save()
 
+It is also possible to construct a custom 2D profile object and then use the
+``from_profile`` method to create a ``PhasePlot`` using the profile object.
+This will sometimes be faster, especially if you need custom x and y axes
+limits.  The following example illustrates this workflow:
+
+.. python-script::
+
+   import yt
+   ds = yt.load("sizmbhloz-clref04SNth-rs9_a0.9011/sizmbhloz-clref04SNth-rs9_a0.9011.art")
+   center = ds.arr([64.0, 64.0, 64.0], 'code_length')
+   rvir = ds.quan(1e-1, "Mpccm/h")
+   sph = ds.sphere(center, rvir)
+   units = dict(density='Msun/pc**3', cell_mass='Msun')
+   extrema = dict(density=(1e-5, 1e1), temperature=(1, 1e7))
+
+   profile = yt.create_profile(sph, ['density', 'temperature'],
+                               n_bins=[128, 128], fields=['cell_mass'],
+                               weight_field=None, units=units, extrema=extrema)
+
+   plot = yt.PhasePlot.from_profile(profile)
+
+   plot.save()
+
 Probability Distribution Functions and Accumulation
 ---------------------------------------------------
 

diff -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced -r d7567af2927271ee6d4c5366bc8920b93bac161e yt/data_objects/profiles.py
--- a/yt/data_objects/profiles.py
+++ b/yt/data_objects/profiles.py
@@ -1196,7 +1196,8 @@
     extrema : dict of min, max tuples
         Minimum and maximum values of the bin_fields for the profiles.
         The keys correspond to the field names. Defaults to the extrema
-        of the bin_fields of the dataset.
+        of the bin_fields of the dataset. If a units dict is provided, extrema
+        are understood to be in the units specified in the dictionary.
     logs : dict of boolean values
         Whether or not to log the bin_fields for the profiles.
         The keys correspond to the field names. Defaults to the take_log
@@ -1245,6 +1246,16 @@
         raise NotImplementedError
     bin_fields = data_source._determine_fields(bin_fields)
     fields = data_source._determine_fields(fields)
+    if units is not None:
+        dummy = {}
+        for item in units:
+            dummy[data_source._determine_fields(item)[0]] = units[item]
+        units.update(dummy)
+    if extrema is not None:
+        dummy = {}
+        for item in extrema:
+            dummy[data_source._determine_fields(item)[0]] = extrema[item]
+        extrema.update(dummy)
     if weight_field is not None:
         weight_field, = data_source._determine_fields([weight_field])
     if not iterable(n_bins):
@@ -1262,12 +1273,16 @@
     else:
         ex = []
         for bin_field in bin_fields:
-            bf_units = data_source.pf._get_field_info(bin_field[0],
-                                                      bin_field[1]).units
+            bf_units = data_source.pf._get_field_info(
+                bin_field[0], bin_field[1]).units
             try:
                 field_ex = list(extrema[bin_field[-1]])
             except KeyError:
                 field_ex = list(extrema[bin_field])
+            if bin_field in units:
+                fe = data_source.pf.arr(field_ex, units[bin_field])
+                fe.convert_to_units(bf_units)
+                field_ex = [fe[0].v, fe[1].v]
             if iterable(field_ex[0]):
                 field_ex[0] = data_source.pf.quan(field_ex[0][0], field_ex[0][1])
                 field_ex[0] = field_ex[0].in_units(bf_units)

diff -r 8bf473d2ff5ef88923c2d2384f2355d3d390fced -r d7567af2927271ee6d4c5366bc8920b93bac161e yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -873,7 +873,8 @@
         """
         obj = cls.__new__(cls)
         data_source = profile.data_source
-        return cls._initialize_instance(obj, data_source, profile, figure_size, fontsize)
+        return cls._initialize_instance(obj, data_source, profile, fontsize,
+                                        figure_size)
 
     def save(self, name=None, mpl_kwargs=None):
         r"""


https://bitbucket.org/yt_analysis/yt/commits/8f2015a0da27/
Changeset:   8f2015a0da27
Branch:      yt-3.0
User:        MatthewTurk
Date:        2014-07-14 19:57:34
Summary:     Merged in ngoldbaum/yt/yt-3.0 (pull request #996)

Streamlining ProfilePlot and PhasePlot creation, adding tests
Affected #:  6 files

diff -r 8676f068d48fae5fcc84d69f000686e27c74167c -r 8f2015a0da2717edbb82f2dbd4f2073b0d95b63c doc/source/visualizing/plots.rst
--- a/doc/source/visualizing/plots.rst
+++ b/doc/source/visualizing/plots.rst
@@ -772,8 +772,8 @@
    ds = yt.load("sizmbhloz-clref04SNth-rs9_a0.9011/sizmbhloz-clref04SNth-rs9_a0.9011.art")
    center = ds.arr([64.0, 64.0, 64.0], 'code_length')
    rvir = ds.quan(1e-1, "Mpccm/h")
+   sph = ds.sphere(center, rvir)
 
-   sph = ds.sphere(center, rvir)
    plot = yt.PhasePlot(sph, "density", "temperature", "cell_mass",
                        weight_field=None)
    plot.set_unit('density', 'Msun/pc**3')
@@ -782,6 +782,29 @@
    plot.set_ylim(1,1e7)
    plot.save()
 
+It is also possible to construct a custom 2D profile object and then use the
+``from_profile`` method to create a ``PhasePlot`` using the profile object.
+This will sometimes be faster, especially if you need custom x and y axes
+limits.  The following example illustrates this workflow:
+
+.. python-script::
+
+   import yt
+   ds = yt.load("sizmbhloz-clref04SNth-rs9_a0.9011/sizmbhloz-clref04SNth-rs9_a0.9011.art")
+   center = ds.arr([64.0, 64.0, 64.0], 'code_length')
+   rvir = ds.quan(1e-1, "Mpccm/h")
+   sph = ds.sphere(center, rvir)
+   units = dict(density='Msun/pc**3', cell_mass='Msun')
+   extrema = dict(density=(1e-5, 1e1), temperature=(1, 1e7))
+
+   profile = yt.create_profile(sph, ['density', 'temperature'],
+                               n_bins=[128, 128], fields=['cell_mass'],
+                               weight_field=None, units=units, extrema=extrema)
+
+   plot = yt.PhasePlot.from_profile(profile)
+
+   plot.save()
+
 Probability Distribution Functions and Accumulation
 ---------------------------------------------------
 

diff -r 8676f068d48fae5fcc84d69f000686e27c74167c -r 8f2015a0da2717edbb82f2dbd4f2073b0d95b63c yt/data_objects/profiles.py
--- a/yt/data_objects/profiles.py
+++ b/yt/data_objects/profiles.py
@@ -1196,7 +1196,8 @@
     extrema : dict of min, max tuples
         Minimum and maximum values of the bin_fields for the profiles.
         The keys correspond to the field names. Defaults to the extrema
-        of the bin_fields of the dataset.
+        of the bin_fields of the dataset. If a units dict is provided, extrema
+        are understood to be in the units specified in the dictionary.
     logs : dict of boolean values
         Whether or not to log the bin_fields for the profiles.
         The keys correspond to the field names. Defaults to the take_log
@@ -1245,6 +1246,16 @@
         raise NotImplementedError
     bin_fields = data_source._determine_fields(bin_fields)
     fields = data_source._determine_fields(fields)
+    if units is not None:
+        dummy = {}
+        for item in units:
+            dummy[data_source._determine_fields(item)[0]] = units[item]
+        units.update(dummy)
+    if extrema is not None:
+        dummy = {}
+        for item in extrema:
+            dummy[data_source._determine_fields(item)[0]] = extrema[item]
+        extrema.update(dummy)
     if weight_field is not None:
         weight_field, = data_source._determine_fields([weight_field])
     if not iterable(n_bins):
@@ -1262,12 +1273,16 @@
     else:
         ex = []
         for bin_field in bin_fields:
-            bf_units = data_source.pf._get_field_info(bin_field[0],
-                                                      bin_field[1]).units
+            bf_units = data_source.pf._get_field_info(
+                bin_field[0], bin_field[1]).units
             try:
                 field_ex = list(extrema[bin_field[-1]])
             except KeyError:
                 field_ex = list(extrema[bin_field])
+            if bin_field in units:
+                fe = data_source.pf.arr(field_ex, units[bin_field])
+                fe.convert_to_units(bf_units)
+                field_ex = [fe[0].v, fe[1].v]
             if iterable(field_ex[0]):
                 field_ex[0] = data_source.pf.quan(field_ex[0][0], field_ex[0][1])
                 field_ex[0] = field_ex[0].in_units(bf_units)

diff -r 8676f068d48fae5fcc84d69f000686e27c74167c -r 8f2015a0da2717edbb82f2dbd4f2073b0d95b63c yt/testing.py
--- a/yt/testing.py
+++ b/yt/testing.py
@@ -1,5 +1,5 @@
 """
-
+Utilities to aid testing.
 
 
 """

diff -r 8676f068d48fae5fcc84d69f000686e27c74167c -r 8f2015a0da2717edbb82f2dbd4f2073b0d95b63c yt/visualization/profile_plotter.py
--- a/yt/visualization/profile_plotter.py
+++ b/yt/visualization/profile_plotter.py
@@ -31,15 +31,15 @@
     ImagePlotContainer, \
     log_transform, linear_transform
 from yt.data_objects.profiles import \
-     create_profile
+    create_profile
 from yt.utilities.exceptions import \
-     YTNotInsideNotebook
+    YTNotInsideNotebook
 from yt.utilities.logger import ytLogger as mylog
 import _mpl_imports as mpl
 from yt.funcs import \
-     ensure_list, \
-     get_image_suffix, \
-     get_ipython_api_version
+    ensure_list, \
+    get_image_suffix, \
+    get_ipython_api_version
 
 def get_canvas(name):
     suffix = get_image_suffix(name)
@@ -150,10 +150,6 @@
         A dictionary or list of dictionaries containing plot keyword 
         arguments.  For example, dict(color="red", linestyle=":").
         Default: None.
-    profiles : list of profiles
-        If not None, a list of profile objects created with 
-        `yt.data_objects.profiles.create_profile`.
-        Default: None.
 
     Examples
     --------
@@ -196,48 +192,37 @@
     z_log = None
     x_title = None
     y_title = None
-
     _plot_valid = False
 
-    def __init__(self, data_source, x_field, y_fields, 
+    def __init__(self, data_source, x_field, y_fields,
                  weight_field="cell_mass", n_bins=64,
                  accumulation=False, fractional=False,
-                 label=None, plot_spec=None, profiles=None):
-        self.y_log = {}
-        self.y_title = {}
-        self.x_log = None
-        if profiles is None:
-            self.profiles = [create_profile(data_source, [x_field],
-                                            n_bins=[n_bins],
-                                            fields=ensure_list(y_fields),
-                                            weight_field=weight_field,
-                                            accumulation=accumulation,
-                                            fractional=fractional)]
-        else:
-            self.profiles = ensure_list(profiles)
-        
-        self.label = sanitize_label(label, len(self.profiles))
+                 label=None, plot_spec=None):
 
-        self.plot_spec = plot_spec
-        if self.plot_spec is None:
-            self.plot_spec = [dict() for p in self.profiles]
-        if not isinstance(self.plot_spec, list):
-            self.plot_spec = [self.plot_spec.copy() for p in self.profiles]
+        profiles = [create_profile(data_source, [x_field],
+                                   n_bins=[n_bins],
+                                   fields=ensure_list(y_fields),
+                                   weight_field=weight_field,
+                                   accumulation=accumulation,
+                                   fractional=fractional)]
 
-        self.figures = FigureContainer()
-        self.axes = AxesContainer(self.figures)
-        self._setup_plots()
-        
+        if plot_spec is None:
+            plot_spec = [dict() for p in profiles]
+        if not isinstance(plot_spec, list):
+            plot_spec = [plot_spec.copy() for p in profiles]
+
+        ProfilePlot._initialize_instance(self, profiles, label, plot_spec)
+
     def save(self, name=None):
         r"""
-        Saves a 1d profile plot.
+         Saves a 1d profile plot.
 
-        Parameters
-        ----------
-        name : str
-            The output file keyword.
-        
-        """
+         Parameters
+         ----------
+         name : str
+             The output file keyword.
+
+         """
         if not self._plot_valid:
             self._setup_plots()
         unique = set(self.figures.values())
@@ -259,14 +244,15 @@
         if not suffix:
             suffix = ".png"
         canvas_cls = get_canvas(name)
+        fns = []
         for uid, fig in iters:
             if isinstance(uid, types.TupleType):
                 uid = uid[1]
             canvas = canvas_cls(fig)
-            fn = "%s_1d-Profile_%s_%s%s" % (prefix, xfn, uid, suffix)
-            mylog.info("Saving %s", fn)
-            canvas.print_figure(fn)
-        return self
+            fns.append("%s_1d-Profile_%s_%s%s" % (prefix, xfn, uid, suffix))
+            mylog.info("Saving %s", fns[-1])
+            canvas.print_figure(fns[-1])
+        return fns
 
     def show(self):
         r"""This will send any existing plots to the IPython notebook.
@@ -323,7 +309,7 @@
             for field, field_data in profile.items():
                 self.axes[field].plot(np.array(profile.x), np.array(field_data),
                                       label=self.label[i], **self.plot_spec[i])
-        
+
         # This relies on 'profile' leaking
         for fname, axes in self.axes.items():
             xscale, yscale = self._get_field_log(fname, profile)
@@ -338,27 +324,43 @@
         self._plot_valid = True
 
     @classmethod
+    def _initialize_instance(cls, obj, profiles, labels, plot_specs):
+        obj.y_log = {}
+        obj.y_title = {}
+        obj.x_log = None
+        obj.profiles = ensure_list(profiles)
+        obj.label = sanitize_label(labels, len(obj.profiles))
+        if plot_specs is None:
+            plot_specs = [dict() for p in obj.profiles]
+        obj.plot_spec = plot_specs
+        obj.figures = FigureContainer()
+        obj.axes = AxesContainer(obj.figures)
+        obj._setup_plots()
+        return obj
+
+    @classmethod
     def from_profiles(cls, profiles, labels=None, plot_specs=None):
         r"""
-        Instantiate a ProfilePlot object from a list of profiles 
-        created with `yt.data_objects.profiles.create_profile`.
+        Instantiate a ProfilePlot object from a list of profiles
+        created with :func:`~yt.data_objects.profiles.create_profile`.
 
         Parameters
         ----------
-        profiles : list of profiles
-            If not None, a list of profile objects created with 
-            `yt.data_objects.profiles.create_profile`.
+        profiles : a profile or list of profiles
+            A single profile or list of profile objects created with
+            :func:`~yt.data_objects.profiles.create_profile`.
         labels : list of strings
             A list of labels for each profile to be overplotted.
             Default: None.
         plot_specs : list of dicts
-            A list of dictionaries containing plot keyword 
+            A list of dictionaries containing plot keyword
             arguments.  For example, [dict(color="red", linestyle=":")].
             Default: None.
 
         Examples
         --------
 
+        >>> from yt import simulation
         >>> es = simulation("AMRCosmology.enzo", "Enzo")
         >>> es.get_time_series()
 
@@ -382,9 +384,8 @@
             raise RuntimeError("Profiles list and labels list must be the same size.")
         if plot_specs is not None and len(plot_specs) != len(profiles):
             raise RuntimeError("Profiles list and plot_specs list must be the same size.")
-        obj = cls(None, None, None, profiles=profiles, label=labels,
-                  plot_spec=plot_specs)
-        return obj
+        obj = cls.__new__(cls)
+        return cls._initialize_instance(obj, profiles, labels, plot_specs)
 
     @invalidate_plot
     def set_line_property(self, property, value, index=None):
@@ -602,7 +603,7 @@
         fractional = profile.fractional
         x_title = self.x_title or self._get_field_label(field_x, xfi, x_unit)
         y_title = self.y_title.get(field_y, None) or \
-                    self._get_field_label(field_y, yfi, y_unit, fractional)
+            self._get_field_label(field_y, yfi, y_unit, fractional)
 
         return (x_title, y_title)
 
@@ -656,9 +657,6 @@
     fontsize: int
         Font size for all text in the plot.
         Default: 18.
-    font_color : str
-        Color for all text in the plot.
-        Default: "black"
     figure_size : int
         Size in inches of the image.
         Default: 8 (8x8)
@@ -691,27 +689,32 @@
     def __init__(self, data_source, x_field, y_field, z_fields,
                  weight_field="cell_mass", x_bins=128, y_bins=128,
                  accumulation=False, fractional=False,
-                 profile=None, fontsize=18, font_color="black", figure_size=8.0):
-        self.plot_title = {}
-        self.z_log = {}
-        self.z_title = {}
-        self._initfinished = False
-        self.x_log = None
-        self.y_log = None
+                 fontsize=18, figure_size=8.0):
 
-        if profile is None:
-            profile = create_profile(data_source,
-               [x_field, y_field],
-               ensure_list(z_fields),
-               n_bins = [x_bins, y_bins],
-               weight_field = weight_field,
-               accumulation=accumulation,
-               fractional=fractional)
-        self.profile = profile
-        super(PhasePlot, self).__init__(data_source, figure_size, fontsize)
-        # This is a fallback, in case we forget.
-        self._setup_plots()
-        self._initfinished = True
+        profile = create_profile(
+            data_source,
+            [x_field, y_field],
+            ensure_list(z_fields),
+            n_bins=[x_bins, y_bins],
+            weight_field=weight_field,
+            accumulation=accumulation,
+            fractional=fractional)
+
+        type(self)._initialize_instance(self, data_source, profile, fontsize, figure_size)
+
+    @classmethod
+    def _initialize_instance(cls, obj, data_source, profile, fontsize, figure_size):
+        obj.plot_title = {}
+        obj.z_log = {}
+        obj.z_title = {}
+        obj._initfinished = False
+        obj.x_log = None
+        obj.y_log = None
+        obj.profile = profile
+        super(PhasePlot, obj).__init__(data_source, figure_size, fontsize)
+        obj._setup_plots()
+        obj._initfinished = True
+        return obj
 
     def _get_field_title(self, field_z, profile):
         pf = profile.data_source.pf
@@ -729,7 +732,7 @@
         x_title = self.x_title or self._get_field_label(field_x, xfi, x_unit)
         y_title = self.y_title or self._get_field_label(field_y, yfi, y_unit)
         z_title = self.z_title.get(field_z, None) or \
-                    self._get_field_label(field_z, zfi, z_unit, fractional)
+            self._get_field_label(field_z, zfi, z_unit, fractional)
         return (x_title, y_title, z_title)
 
     def _get_field_label(self, field, field_info, field_unit, fractional=False):
@@ -837,6 +840,42 @@
                     label.set_color(self._font_color)
         self._plot_valid = True
 
+    @classmethod
+    def from_profile(cls, profile, fontsize=18, figure_size=8.0):
+        r"""
+        Instantiate a PhasePlot object from a profile object created
+        with :func:`~yt.data_objects.profiles.create_profile`.
+
+        Parameters
+        ----------
+        profile : An instance of :class:`~yt.data_objects.profiles.ProfileND`
+             A single profile object.
+        fontsize : float
+             The fontsize to use, in points.
+        figure_size : float
+             The figure size to use, in inches.
+
+        Examples
+        --------
+
+        >>> import yt
+        >>> ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
+        >>> extrema = {
+        ... 'density': (1e-31, 1e-24),
+        ... 'temperature': (1e1, 1e8),
+        ... 'cell_mass': (1e-6, 1e-1),
+        ... }
+        >>> profile = yt.create_profile(ds.all_data(), ['density', 'temperature'],
+        ...                             fields=['cell_mass'],extrema=extrema,
+        ...                             fractional=True)
+        >>> ph = yt.PhasePlot.from_profile(profile)
+        >>> ph.save()
+        """
+        obj = cls.__new__(cls)
+        data_source = profile.data_source
+        return cls._initialize_instance(obj, data_source, profile, fontsize,
+                                        figure_size)
+
     def save(self, name=None, mpl_kwargs=None):
         r"""
         Saves a 2d profile plot.

diff -r 8676f068d48fae5fcc84d69f000686e27c74167c -r 8f2015a0da2717edbb82f2dbd4f2073b0d95b63c yt/visualization/tests/test_plotwindow.py
--- a/yt/visualization/tests/test_plotwindow.py
+++ b/yt/visualization/tests/test_plotwindow.py
@@ -61,7 +61,7 @@
     return image_type == os.path.splitext(fname)[1]
 
 
-TEST_FLNMS = [None, 'test.png', 'test.eps',
+TEST_FLNMS = [None, 'test', 'test.png', 'test.eps',
               'test.ps', 'test.pdf']
 M7 = "DD0010/moving7_0010"
 WT = "WindTunnel/windtunnel_4lev_hdf5_plt_cnt_0030"

diff -r 8676f068d48fae5fcc84d69f000686e27c74167c -r 8f2015a0da2717edbb82f2dbd4f2073b0d95b63c yt/visualization/tests/test_profile_plots.py
--- /dev/null
+++ b/yt/visualization/tests/test_profile_plots.py
@@ -0,0 +1,85 @@
+"""
+Testsuite for ProfilePlot and PhasePlot
+
+
+
+"""
+
+#-----------------------------------------------------------------------------
+# 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.
+#-----------------------------------------------------------------------------
+import itertools
+import os
+import tempfile
+import shutil
+import unittest
+from yt.data_objects.profiles import create_profile
+from yt.extern.parameterized import\
+    parameterized, param
+from yt.testing import fake_random_pf
+from yt.visualization.profile_plotter import \
+    ProfilePlot, PhasePlot
+from yt.visualization.tests.test_plotwindow import \
+    assert_fname, TEST_FLNMS
+
+class TestProfilePlotSave(unittest.TestCase):
+
+    @classmethod
+    def setUpClass(cls):
+        fields = ('density', 'temperature', 'velocity_x', 'velocity_y',
+                  'velocity_z')
+        units = ('g/cm**3', 'K', 'cm/s', 'cm/s', 'cm/s')
+        test_ds = fake_random_pf(64, fields=fields, units=units)
+        regions = [test_ds.region([0.5]*3, [0.4]*3, [0.6]*3), test_ds.all_data()]
+        profiles = []
+        phases = []
+        pr_fields = [('density', 'temperature'), ('density', 'velocity_x'),
+                     ('temperature', 'cell_mass'), ('density', 'radius'),
+                     ('velocity_magnitude', 'cell_mass')]
+        ph_fields = [('density', 'temperature', 'cell_mass'),
+                     ('density', 'velocity_x', 'cell_mass'),
+                     ('radius', 'temperature', 'velocity_magnitude')]
+        for reg in regions:
+            for x_field, y_field in pr_fields:
+                profiles.append(ProfilePlot(reg, x_field, y_field))
+                profiles.append(ProfilePlot(reg, x_field, y_field,
+                                            fractional=True, accumulation=True))
+                p1d = create_profile(reg, x_field, y_field)
+                profiles.append(ProfilePlot.from_profiles(p1d))
+            for x_field, y_field, z_field in ph_fields:
+                # set n_bins to [16, 16] since matplotlib's postscript
+                # renderer is slow when it has to write a lot of polygons
+                phases.append(PhasePlot(reg, x_field, y_field, z_field,
+                                        x_bins=16, y_bins=16))
+                phases.append(PhasePlot(reg, x_field, y_field, z_field,
+                                        fractional=True, accumulation=True,
+                                        x_bins=16, y_bins=16))
+                p2d = create_profile(reg, [x_field, y_field], z_field,
+                                     n_bins=[16, 16])
+                phases.append(PhasePlot.from_profile(p2d))
+        cls.profiles = profiles
+        cls.phases = phases
+        cls.ds = test_ds
+
+    def setUp(self):
+        self.tmpdir = tempfile.mkdtemp()
+        self.curdir = os.getcwd()
+        os.chdir(self.tmpdir)
+
+    def tearDown(self):
+        os.chdir(self.curdir)
+        shutil.rmtree(self.tmpdir)
+
+    @parameterized.expand(param.explicit((fname, )) for fname in TEST_FLNMS)
+    def test_profile_plot(self, fname):
+        for p in self.profiles:
+            yield assert_fname(p.save(fname)[0])
+
+    @parameterized.expand(param.explicit((fname, )) for fname in TEST_FLNMS)
+    def test_phase_plot(self, fname):
+        for p in self.phases:
+            assert assert_fname(p.save(fname)[0])

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