Repository: yt-project/yt

Issue:
Reloaded slices and projections cannot be visualized with SlicePlot and ProjectionPlot as advertised in the docs
According to this page in the docs:

http://yt-project.org/doc/analyzing/saving_data.html#spatial-plots

Something like the following script should work:

```python
import yt
ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
plot = yt.SlicePlot(ds, 'z', 'density')
plot.data_source.save_as_dataset('slice.h5')
ds_slice = yt.load('slice.h5')
p = yt.SlicePlot(ds_slice, 'z', 'density')
```

Unfortunately, right now it errors out with the following traceback:

```
---------------------------------------------------------------------------
YTInvalidFieldType                        Traceback (most recent call last)
/Users/goldbaum/Documents/yt-git-fixes/yt/mods.py in <module>()
----> 1 p = yt.SlicePlot(ds_slice, 'z', 'density')

/Users/goldbaum/Documents/yt-git-fixes/yt/visualization/plot_window.py in SlicePlot(ds, normal, fields, axis, *args, **kwargs)
   2014             del kwargs['north_vector']
   2015
-> 2016         return AxisAlignedSlicePlot(ds, normal, fields, *args, **kwargs)

/Users/goldbaum/Documents/yt-git-fixes/yt/visualization/plot_window.py in __init__(self, ds, axis, fields, center, width, axes_unit, origin, right_handed, fontsize, field_parameters, window_size, aspect, data_source)
   1328                            center=center, data_source=data_source)
   1329             slc.get_data(fields)
-> 1330         validate_mesh_fields(slc, fields)
   1331         PWViewerMPL.__init__(self, slc, bounds, origin=origin,
   1332                              fontsize=fontsize, fields=fields,

/Users/goldbaum/Documents/yt-git-fixes/yt/visualization/plot_window.py in validate_mesh_fields(data_source, fields)
    138
    139     if len(invalid_fields) > 0:
--> 140         raise YTInvalidFieldType(invalid_fields)
    141
    142

YTInvalidFieldType:
SlicePlot, ProjectionPlot, and OffAxisProjectionPlot can only plot fields that
are defined on a mesh, but received the following particle fields:

    [('all', 'density')]

Did you mean to use ParticlePlot or plot a deposited particle field instead?
```

So either the documentation needs to be updated to indicate that you need to use ParticlePlot if you do this or this used to work and something has broken in the meantime. @brittonsmith do you remember whether this ever worked?
Reloaded slices and projections cannot be visualized with SlicePlot and ProjectionPlot as advertised in the docs
According to this page in the docs:

http://yt-project.org/doc/analyzing/saving_data.html#spatial-plots

Something like the following script should work:

```python
import yt
ds = yt.load('IsolatedGalaxy/galaxy0030/galaxy0030')
plot = yt.SlicePlot(ds, 'z', 'density')
plot.data_source.save_as_dataset('slice.h5')
ds_slice = yt.load('slice.h5')
p = yt.SlicePlot(ds_slice, 'z', 'density')
```

Unfortunately, right now it errors out with the following traceback:

```
---------------------------------------------------------------------------
YTInvalidFieldType                        Traceback (most recent call last)
/Users/goldbaum/Documents/yt-git-fixes/yt/mods.py in <module>()
----> 1 p = yt.SlicePlot(ds_slice, 'z', 'density')

/Users/goldbaum/Documents/yt-git-fixes/yt/visualization/plot_window.py in SlicePlot(ds, normal, fields, axis, *args, **kwargs)
   2014             del kwargs['north_vector']
   2015
-> 2016         return AxisAlignedSlicePlot(ds, normal, fields, *args, **kwargs)

/Users/goldbaum/Documents/yt-git-fixes/yt/visualization/plot_window.py in __init__(self, ds, axis, fields, center, width, axes_unit, origin, right_handed, fontsize, field_parameters, window_size, aspect, data_source)
   1328                            center=center, data_source=data_source)
   1329             slc.get_data(fields)
-> 1330         validate_mesh_fields(slc, fields)
   1331         PWViewerMPL.__init__(self, slc, bounds, origin=origin,
   1332                              fontsize=fontsize, fields=fields,

/Users/goldbaum/Documents/yt-git-fixes/yt/visualization/plot_window.py in validate_mesh_fields(data_source, fields)
    138
    139     if len(invalid_fields) > 0:
--> 140         raise YTInvalidFieldType(invalid_fields)
    141
    142

YTInvalidFieldType:
SlicePlot, ProjectionPlot, and OffAxisProjectionPlot can only plot fields that
are defined on a mesh, but received the following particle fields:

    [('all', 'density')]

Did you mean to use ParticlePlot or plot a deposited particle field instead?
```

So either the documentation needs to be updated to indicate that you need to use ParticlePlot if you do this or this used to work and something has broken in the meantime. @brittonsmith do you remember whether this ever worked?


Discussion:
I can confirm that this did work when I put it in the documentation, but I guess it wasn't being tested.  I won't have time to look at this for a couple weeks, but I can try then.
Verified just now that it works on the changeset that added the feature. I'm going to see if I can bisect now...
Bisects to this commit:

```
commit 8b7bd89c55ef6c66bfe54ff4494da771f82d532a
Author: Nathan Goldbaum <ngoldbau@illinois.edu>
Date:   Sat Jul 16 10:36:56 2016 -0500

    Print a more informative error message when PlotWindow is passed a particle field

    Closes #878

    --HG--
    branch : yt
```
I can confirm that this did work when I put it in the documentation, but I guess it wasn't being tested.  I won't have time to look at this for a couple weeks, but I can try then.
Verified just now that it works on the changeset that added the feature. I'm going to see if I can bisect now...
Bisects to this commit:

```
commit 8b7bd89c55ef6c66bfe54ff4494da771f82d532a
Author: Nathan Goldbaum <ngoldbau@illinois.edu>
Date:   Sat Jul 16 10:36:56 2016 -0500

    Print a more informative error message when PlotWindow is passed a particle field

    Closes #878

    --HG--
    branch : yt
```

Resolving patch:
diff --git a/yt/visualization/plot_window.py b/yt/visualization/plot_window.py
--- a/yt/visualization/plot_window.py
+++ b/yt/visualization/plot_window.py
@@ -124,6 +124,11 @@ def get_axes_unit(width, ds):
     return axes_unit
 
 def validate_mesh_fields(data_source, fields):
+    # this check doesn't make sense for ytdata plot datasets, which
+    # load mesh data as a particle field but nonetheless can still
+    # make plots with it
+    if isinstance(data_source.ds, YTSpatialPlotDataset):
+        return
     canonical_fields = data_source._determine_fields(fields)
     invalid_fields = []
     for field in canonical_fields:
@@ -1438,7 +1443,10 @@ def __init__(self, ds, axis, fields, center='c', width=None, axes_unit=None,
             if proj.axis != ds.parameters["axis"]:
                 raise RuntimeError("Original projection axis is %s." %
                                    ds.parameters["axis"])
-            proj.weight_field = proj._determine_fields(weight_field)[0]
+            if weight_field is not None:
+                proj.weight_field = proj._determine_fields(weight_field)[0]
+            else:
+                proj.weight_field = weight_field
         else:
             proj = ds.proj(fields, axis, weight_field=weight_field,
                            center=center, data_source=data_source,
@@ -2060,4 +2068,4 @@ def plot_2d(ds, fields, center='c', width=None, axes_unit=None,
                                 fontsize=fontsize,
                                 field_parameters=field_parameters, 
                                 window_size=window_size, aspect=aspect,
-                                data_source=data_source)
\ No newline at end of file
+                                data_source=data_source)


Test patch:
diff --git a/yt/frontends/ytdata/tests/test_outputs.py b/yt/frontends/ytdata/tests/test_outputs.py
--- a/yt/frontends/ytdata/tests/test_outputs.py
+++ b/yt/frontends/ytdata/tests/test_outputs.py
@@ -26,7 +26,9 @@
     save_as_dataset
 from yt.testing import \
     assert_allclose_units, \
-    assert_equal
+    assert_equal, \
+    assert_fname, \
+    fake_random_ds
 from yt.utilities.answer_testing.framework import \
     requires_ds, \
     data_dir_load, \
@@ -34,6 +36,9 @@
 from yt.units.yt_array import \
     YTArray, \
     YTQuantity
+from yt.visualization.plot_window import \
+    SlicePlot, \
+    ProjectionPlot
 from yt.visualization.profile_plotter import \
     ProfilePlot, \
     PhasePlot
@@ -223,3 +228,33 @@ def test_nonspatial_data():
     yield YTDataFieldTest(full_fn, "density", geometric=False)
     os.chdir(curdir)
     shutil.rmtree(tmpdir)
+
+def test_plot_data():
+    tmpdir = tempfile.mkdtemp()
+    curdir = os.getcwd()
+    os.chdir(tmpdir)
+    ds = fake_random_ds(16)
+
+    plot = SlicePlot(ds, 'z', 'density')
+    plot.data_source.save_as_dataset('slice.h5')
+    ds_slice = load('slice.h5')
+    p = SlicePlot(ds_slice, 'z', 'density')
+    fn = p.save()
+    assert_fname(fn[0])
+
+    plot = ProjectionPlot(ds, 'z', 'density')
+    plot.data_source.save_as_dataset('proj.h5')
+    ds_proj = load('slice.h5')
+    p = ProjectionPlot(ds_proj, 'z', 'density')
+    fn = p.save()
+    assert_fname(fn[0])
+
+    plot = SlicePlot(ds, [1, 1, 1], 'density')
+    plot.data_source.save_as_dataset('oas.h5')
+    ds_oas = load('oas.h5')
+    p = SlicePlot(ds_oas, [1, 1, 1], 'density')
+    fn = p.save()
+    assert_fname(fn[0])
+
+    os.chdir(curdir)
+    shutil.rmtree(tmpdir)