<html><body>
<p>10 new commits in yt:</p>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/5efa040e141e/">https://bitbucket.org/yt_analysis/yt/commits/5efa040e141e/</a> Changeset:   5efa040e141e Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:00:20+00:00 Summary:     imports: move import of cyglfw3 and OpenGL.GL out of the top-level imports Affected #:  1 file</p>
<p>diff -r 77db965d0a537a9884d6db3c5ad7595dc3070ba0 -r 5efa040e141e784ac1388d2e3ab84389fcc6046b yt/visualization/volume_rendering/interactive_vr_helpers.py --- a/yt/visualization/volume_rendering/interactive_vr_helpers.py +++ b/yt/visualization/volume_rendering/interactive_vr_helpers.py @@ -17,7 +17,6 @@</p>
<pre>from yt.funcs import mylog
from yt.data_objects.static_output import Dataset
from yt.utilities.exceptions import YTSceneFieldNotFound</pre>
<p>-from yt.utilities.on_demand_imports import NotAModule</p>
<pre>def _render_opengl(data_source, field=None, window_size=None, cam_position=None,
                   cam_focus=None):</pre>
<p>@@ -52,6 +51,13 @@</p>
<pre>    '''
</pre>
<p>+    try: +        import cyglfw3  # NOQA +        import OpenGL.GL  # NOQA +    except ImportError: +        raise ImportError("This functionality requires the cyglfw3 and PyOpenGL " +                          “packages to be installed.”) +</p>
<pre>    from .interactive_vr import SceneGraph, BlockCollection, TrackballCamera
    from .interactive_loop import RenderingContext
</pre>
<p>@@ -87,9 +93,4 @@</p>
<pre>    rc.start_loop(scene, c)

</pre>
<p>-try:</p>
<ul><li><p>import cyglfw3 as glfw  # NOQA</p></li>
<li><p>import OpenGL.GL as GL  # NOQA</p></li>
<li><p>interactive_render = _render_opengl</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>interactive_render = NotAModule("opengl/cyglfw3")</p></li></ul>
<p>+interactive_render = _render_opengl</p>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/b1775d48b52b/">https://bitbucket.org/yt_analysis/yt/commits/b1775d48b52b/</a> Changeset:   b1775d48b52b Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:02:11+00:00 Summary:     imports: avoid importing nose at the top level in yt.testing</p>
<p>This requires copying a bit of boilerplate from nose so we can define two assert functions used in yt that we've gotten from nose until now. These imports are just API shims on top of unittest.TestCase member functions, so we build the necessary shims ourselves. Affected #:  1 file</p>
<p>diff -r 5efa040e141e784ac1388d2e3ab84389fcc6046b -r b1775d48b52bbf04e55fac3305ca34a8c5d5f35d yt/testing.py --- a/yt/testing.py +++ b/yt/testing.py @@ -20,6 +20,8 @@</p>
<pre>import numpy as np
import importlib
import os</pre>
<p>+import re +import unittest</p>
<pre>from yt.funcs import iterable
from yt.config import ytcfg
# we import this in a weird way from numpy.testing to avoid triggering</pre>
<p>@@ -31,16 +33,23 @@</p>
<pre>from numpy.testing import assert_string_equal  # NOQA
from numpy.testing import assert_array_almost_equal_nulp  # NOQA
from numpy.testing import assert_allclose, assert_raises  # NOQA</pre>
<p>-try:</p>
<ul><li><p>from nose.tools import assert_true, assert_less_equal  # NOQA</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p># This means nose isn't installed, so the tests can't run and it's ok</p></li>
<li><p># to not import these functions</p></li>
<li><p>pass</p></li></ul>
<p>+from unittest import TestCase</p>
<pre>from yt.convenience import load
from yt.units.yt_array import YTArray, YTQuantity
from yt.utilities.exceptions import YTUnitOperationError
</pre>
<p>+# Expose assert_true and assert_less_equal from unittest.TestCase +# this is adopted from nose. Doing this here allows us to avoid importing +# nose at the top level. +class _Dummy(unittest.TestCase): +    def nop(): +        pass +_t = _Dummy('nop') + +assert_true = getattr(_t, ‘assertTrue’) +assert_less_equal = getattr(_t, ‘assertLessEqual’) + +</p>
<pre>def assert_rel_equal(a1, a2, decimals, err_msg='', verbose=True):
    # We have nan checks in here because occasionally we have fields that get
    # weighted without non-zero weights.  I'm looking at you, particle fields!</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/4a5cd8d0b35e/">https://bitbucket.org/yt_analysis/yt/commits/4a5cd8d0b35e/</a> Changeset:   4a5cd8d0b35e Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:03:58+00:00 Summary:     imports: avoid importing requests at the top level Affected #:  4 files</p>
<p>diff -r b1775d48b52bbf04e55fac3305ca34a8c5d5f35d -r 4a5cd8d0b35e0f69636b04fa30b360b3e8558f6f yt/frontends/http_stream/data_structures.py --- a/yt/frontends/http_stream/data_structures.py +++ b/yt/frontends/http_stream/data_structures.py @@ -15,6 +15,7 @@</p>
<pre># The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
</pre>
<p>+import json</p>
<pre>import numpy as np
import time
</pre>
<p>@@ -24,15 +25,11 @@</p>
<pre>    ParticleDataset
from yt.frontends.sph.fields import \
    SPHFieldInfo</pre>
<p>+from yt.funcs import \ +    get_requests</p>
<pre>from yt.geometry.particle_geometry_handler import \
    ParticleIndex
</pre>
<p>-try:</p>
<ul><li><p>import requests</p></li>
<li><p>import json</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>requests = None</p></li></ul>
<p>–</p>
<pre>class HTTPParticleFile(ParticleFile):
    pass
</pre>
<p>@@ -49,8 +46,9 @@</p>
<pre>dataset_type = "http_particle_stream",
n_ref = 64, over_refine_factor=1,
unit_system="cgs"):</pre>
<ul><li><p>if requests is None:</p></li>
<li><p>raise RuntimeError</p></li></ul>
<p>+        if get_requests() is None: +            raise ImportError( +                “This functionality depends on the requests package”)</p>
<pre>self.base_url = base_url
self.n_ref = n_ref
self.over_refine_factor = over_refine_factor</pre>
<p>@@ -66,6 +64,7 @@</p>
<pre>        self.parameters["HydroMethod"] = "sph"

        # Here's where we're going to grab the JSON index file</pre>
<p>+        requests = get_requests()</p>
<pre>         hreq = requests.get(self.base_url + "/yt_index.json")
         if hreq.status_code != 200:
raise RuntimeError</pre>
<p>@@ -108,6 +107,9 @@</p>
<pre>     def _is_valid(self, *args, **kwargs):
         if not args[0].startswith("http://"):
return False</pre>
<p>+        requests = get_requests() +        if requests is None: +            return False</p>
<pre>         hreq = requests.get(args[0] + "/yt_index.json")
         if hreq.status_code == 200:
return True</pre>
<p>diff -r b1775d48b52bbf04e55fac3305ca34a8c5d5f35d -r 4a5cd8d0b35e0f69636b04fa30b360b3e8558f6f yt/frontends/http_stream/io.py --- a/yt/frontends/http_stream/io.py +++ b/yt/frontends/http_stream/io.py @@ -18,24 +18,21 @@</p>
<pre>import numpy as np

from yt.funcs import \</pre>
<p>+    get_requests, \</p>
<pre>    mylog
from yt.utilities.io_handler import \
    BaseIOHandler
from yt.utilities.lib.geometry_utils import \
    compute_morton
</pre>
<p>-try:</p>
<ul><li><p>import requests</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>requests = None</p></li></ul>
<p>–</p>
<pre>class IOHandlerHTTPStream(BaseIOHandler):
    _dataset_type = "http_particle_stream"
    _vector_fields = ("Coordinates", "Velocity", "Velocities")

    def __init__(self, ds):</pre>
<ul><li><p>if requests is None:</p></li>
<li><p>raise RuntimeError</p></li></ul>
<p>+        if get_requests() is None: +            raise ImportError( +                “This functionality depends on the requests package”)</p>
<pre>self._url = ds.base_url
# This should eventually manage the IO and cache it
self.total_bytes = 0</pre>
<p>@@ -47,6 +44,7 @@</p>
<pre>         s = "%s/%s/%s/%s" % (self._url,
data_file.file_id, ftype, fname)
         mylog.info("Loading URL %s", s)</pre>
<p>+        requests = get_requests()</p>
<pre>         resp = requests.get(s)
         if resp.status_code != 200:
raise RuntimeError</pre>
<p>diff -r b1775d48b52bbf04e55fac3305ca34a8c5d5f35d -r 4a5cd8d0b35e0f69636b04fa30b360b3e8558f6f yt/frontends/sdf/data_structures.py --- a/yt/frontends/sdf/data_structures.py +++ b/yt/frontends/sdf/data_structures.py @@ -27,6 +27,8 @@</p>
<pre>    ParticleIndex
from yt.data_objects.static_output import \
    Dataset, ParticleFile</pre>
<p>+from yt.funcs import \ +    get_requests</p>
<pre>from .fields import \
    SDFFieldInfo
from yt.utilities.sdf import \</pre>
<p>@@ -34,11 +36,6 @@</p>
<pre>    SDFIndex,\
    HTTPSDFRead
</pre>
<p>-try:</p>
<ul><li><p>import requests</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>requests = None</p></li></ul>
<p>–</p>
<pre>@contextlib.contextmanager
def safeopen(*args, **kwargs):
    if sys.version[0] != '3':</pre>
<p>@@ -195,7 +192,9 @@</p>
<pre>def _is_valid(cls, *args, **kwargs):
    sdf_header = kwargs.get('sdf_header', args[0])
    if sdf_header.startswith("http"):</pre>
<ul><li><p>if requests is None: return False</p></li></ul>
<p>+            requests = get_requests() +            if requests is None: +                return False</p>
<pre>hreq = requests.get(sdf_header, stream=True)
if hreq.status_code != 200: return False
# Grab a whole 4k page.</pre>
<p>diff -r b1775d48b52bbf04e55fac3305ca34a8c5d5f35d -r 4a5cd8d0b35e0f69636b04fa30b360b3e8558f6f yt/funcs.py --- a/yt/funcs.py +++ b/yt/funcs.py @@ -953,3 +953,10 @@</p>
<pre>         raise RuntimeError(
"Please install palettable to use colorbrewer colormaps")
     return bmap.get_mpl_colormap(N=cmap[2])</pre>
<p>+ +def get_requests(): +    try: +        import requests +    except ImportError: +        requests = None +    return requests</p>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/cfb40c8cf1e9/">https://bitbucket.org/yt_analysis/yt/commits/cfb40c8cf1e9/</a> Changeset:   cfb40c8cf1e9 Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:04:30+00:00 Summary:     imports: avoid importing thingking at the top level Affected #:  1 file</p>
<p>diff -r 4a5cd8d0b35e0f69636b04fa30b360b3e8558f6f -r cfb40c8cf1e9e14c53542c69652618290f7395a3 yt/utilities/sdf.py --- a/yt/utilities/sdf.py +++ b/yt/utilities/sdf.py @@ -2,13 +2,18 @@</p>
<pre>from yt.extern.six.moves import cStringIO
import os
import numpy as np</pre>
<p>-try:</p>
<ul><li><p>from thingking.httpmmap import HTTPArray</p></li>
<li><p>from thingking.arbitrary_page import PageCacheURL</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>HTTPArray = PageCacheURL = None</p></li></ul>
<p>+</p>
<pre>from yt.funcs import mylog
</pre>
<p>+def get_thingking_deps(): +    try: +        from thingking.httpmmap import HTTPArray +        from thingking.arbitrary_page import PageCacheURL +    except ImportError: +        raise ImportError( +            “This functionality requires the thingking package to be installed”) +    return HTTPArray, PageCacheURL +</p>
<pre>_types = {
    'int16_t': 'int16',
    'uint16_t': 'uint16',</pre>
<p>@@ -216,8 +221,8 @@</p>
<pre>def __init__(self, *args, **kwargs):
    super(HTTPDataStruct, self).__init__(*args, **kwargs)</pre>
<ul><li><p>if None in (PageCacheURL, HTTPArray):</p></li>
<li><p>raise ImportError("'thingking' is required for loading of remote HTTP data.")</p></li></ul>
<p>+        HTTPArray, PageCacheURL = get_thingking_deps() +        self.HTTPArray = HTTPArray</p>
<pre>        self.pcu = PageCacheURL(self.filename)

    def set_offset(self, offset):</pre>
<p>@@ -232,7 +237,7 @@</p>
<pre>def build_memmap(self):
    assert(self.size != -1)
    mylog.info('Building memmap with offset: %i and size %i' % (self._offset, self.size))</pre>
<ul><li><p>self.handle = HTTPArray(self.filename, dtype=self.dtype,</p></li></ul>
<p>+        self.handle = self.HTTPArray(self.filename, dtype=self.dtype,</p>
<pre>            shape=self.size, offset=self._offset)
         for k in self.dtype.names:
self.data[k] = RedirectArray(self.handle, k)</pre>
<p>@@ -457,14 +462,14 @@</p>
<pre>    _data_struct = HTTPDataStruct

    def __init__(self, *args, **kwargs):</pre>
<ul><li><p>if None in (PageCacheURL, HTTPArray):</p></li>
<li><p>raise ImportError("thingking")</p></li></ul>
<p>+        HTTPArray, _ = get_thingking_deps() +        self.HTTPArray = HTTPArray</p>
<pre>        super(HTTPSDFRead, self).__init__(*args, **kwargs)

    def parse_header(self):
        """docstring for parse_header"""
        # Pre-process</pre>
<ul><li><p>ascfile = HTTPArray(self.header)</p></li></ul>
<p>+        ascfile = self.HTTPArray(self.header)</p>
<pre>max_header_size = 1024*1024
lines = cStringIO(ascfile[:max_header_size].data[:])
while True:</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/ad98aa4cf655/">https://bitbucket.org/yt_analysis/yt/commits/ad98aa4cf655/</a> Changeset:   ad98aa4cf655 Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:05:06+00:00 Summary:     plotting: remove shim code for ancient matplotlib versions.</p>
<p>matplotlib 0.98 was released in 2008. We don't need to maintain compatibility with versions this old Affected #:  1 file</p>
<p>diff -r cfb40c8cf1e9e14c53542c69652618290f7395a3 -r ad98aa4cf655fed362f593dfd67b7759dafa4ea4 yt/visualization/_mpl_imports.py --- a/yt/visualization/_mpl_imports.py +++ b/yt/visualization/_mpl_imports.py @@ -19,33 +19,3 @@</p>
<pre>from matplotlib.backends.backend_ps import \
    FigureCanvasPS</pre>
<p>– -# Now we provide some convenience functions to get information about plots. -# With Matplotlib 0.98.x, the ‘transforms’ branch broke backwards -# compatibility.  Despite that, the various packagers are plowing ahead with -# packaging 0.98.x with new distributions of python software.  So I guess -# we have to support it. – -_compatibility_functions = ["mpl_get_bounds","mpl_notify"] – -_mpl98_mpl_get_bounds = lambda bbox: bbox.bounds -_mpl9x_mpl_get_bounds = lambda bbox: bbox.get_bounds() -_mpl98_mpl_notify = lambda im,cb: cb.update_bruteforce(im) -_mpl9x_mpl_notify = lambda im,cb: cb.notify(im) – -# This next function hurts, because it relies on the fact that we're -# only differentiating between 0.9[01] and 0.98. And if happens to be -# 1.0, or any version with only 3 values, this should catch it. – -try:</p>
<ul><li><p>_mpl_version = float(matplotlib.__version__[:4])</p></li></ul>
<p>-except:</p>
<ul><li><p>_mpl_version = float(matplotlib.__version__[:3])</p></li></ul>
<p>– -if _mpl_version < 0.98:</p>
<ul><li><p>_prefix = ‘_mpl9x’</p></li></ul>
<p>-else:</p>
<ul><li><p>_prefix = ‘_mpl98’</p></li></ul>
<p>– -for fn in _compatibility_functions:</p>
<ul><li><p>exec("%s = %s_%s" % (fn, _prefix, fn))</p></li></ul>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/a412ed373902/">https://bitbucket.org/yt_analysis/yt/commits/a412ed373902/</a> Changeset:   a412ed373902 Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:06:35+00:00 Summary:     plotting: remove unused imports in _mpl_imports Affected #:  1 file</p>
<p>diff -r ad98aa4cf655fed362f593dfd67b7759dafa4ea4 -r a412ed373902a47f9cd03556bc0064a1c83b1d7d yt/visualization/_mpl_imports.py --- a/yt/visualization/_mpl_imports.py +++ b/yt/visualization/_mpl_imports.py @@ -1,16 +1,6 @@</p>
<pre>import matplotlib
matplotlib.rc('contour', negative_linestyle='solid')
</pre>
<p>-import matplotlib.image -import matplotlib.ticker -import matplotlib.axes -import matplotlib.figure -import matplotlib._image -import matplotlib.colors -import matplotlib.colorbar -import matplotlib.cm -import matplotlib.collections –</p>
<pre>from matplotlib.backends.backend_agg import \
    FigureCanvasAgg
</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/f7881eb5c1eb/">https://bitbucket.org/yt_analysis/yt/commits/f7881eb5c1eb/</a> Changeset:   f7881eb5c1eb Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:07:52+00:00 Summary:     imports: avoid importing from matplotlib internals at the top level Affected #:  8 files</p>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/frontends/fits/misc.py --- a/yt/frontends/fits/misc.py +++ b/yt/frontends/fits/misc.py @@ -16,7 +16,6 @@</p>
<pre>from yt.fields.derived_field import ValidateSpatial
from yt.funcs import mylog
from yt.utilities.on_demand_imports import _astropy</pre>
<p>-from yt.visualization._mpl_imports import FigureCanvasAgg</p>
<pre>from yt.units.yt_array import YTQuantity, YTArray
from yt.utilities.fits_image import FITSImageData
if PY3:</pre>
<p>@@ -258,6 +257,7 @@</p>
<pre>        self.pw.save(name=name, mpl_kwargs=mpl_kwargs)

    def _repr_html_(self):</pre>
<p>+        from yt.visualization._mpl_imports import FigureCanvasAgg</p>
<pre>         ret = ''
         for k, v in self.plots.items():
canvas = FigureCanvasAgg(v)</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/base_plot_types.py --- a/yt/visualization/base_plot_types.py +++ b/yt/visualization/base_plot_types.py @@ -15,8 +15,6 @@</p>
<pre>#-----------------------------------------------------------------------------
from io import BytesIO
import matplotlib</pre>
<p>-from ._mpl_imports import \</p>
<ul><li><p>FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS</p></li></ul>
<pre>from yt.funcs import \
    get_image_suffix, \
    mylog, \</pre>
<p>@@ -57,6 +55,7 @@</p>
<pre>"""
def __init__(self, fsize, axrect, figure, axes):
    """Initialize PlotMPL class"""</pre>
<p>+        from ._mpl_imports import FigureCanvasAgg</p>
<pre>         self._plot_valid = True
         if figure is None:
self.figure = matplotlib.figure.Figure(figsize=fsize, frameon=True)</pre>
<p>@@ -73,6 +72,8 @@</p>
<pre>def save(self, name, mpl_kwargs=None, canvas=None):
    """Choose backend and save image to disk"""</pre>
<p>+        from ._mpl_imports import \ +            FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS</p>
<pre>         if mpl_kwargs is None:
mpl_kwargs = {}
         if 'papertype' not in mpl_kwargs:</pre>
<p>@@ -144,6 +145,7 @@</p>
<pre>            self.cb = self.figure.colorbar(self.image, self.cax)

    def _repr_png_(self):</pre>
<p>+        from ._mpl_imports import FigureCanvasAgg</p>
<pre>canvas = FigureCanvasAgg(self.figure)
f = BytesIO()
canvas.print_figure(f)</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/eps_writer.py --- a/yt/visualization/eps_writer.py +++ b/yt/visualization/eps_writer.py @@ -17,7 +17,6 @@</p>
<pre>import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt</pre>
<p>-from ._mpl_imports import FigureCanvasAgg</p>
<pre>from yt.config import \
    ytcfg</pre>
<p>@@ -509,7 +508,8 @@</p>
<pre>For best results, set use_colorbar=False when creating the yt
image.
"""</pre>
<p>– +        from ._mpl_imports import FigureCanvasAgg +</p>
<pre># We need to remove the colorbar (if necessary), remove the
# axes, and resize the figure to span the entire figure
force_square = False</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/plot_container.py --- a/yt/visualization/plot_container.py +++ b/yt/visualization/plot_container.py @@ -23,9 +23,7 @@</p>
<pre>from collections import defaultdict
from functools import wraps</pre>
<p>-from matplotlib.font_manager import FontProperties</p>
<p>-from ._mpl_imports import FigureCanvasAgg</p>
<pre>from .tick_locators import LogLocator, LinearLocator

from yt.config import \</pre>
<p>@@ -184,6 +182,8 @@</p>
<pre>    _colorbar_valid = False

    def __init__(self, data_source, figure_size, fontsize):</pre>
<p>+        from matplotlib.font_manager import FontProperties +</p>
<pre>         self.data_source = data_source
         if iterable(figure_size):
self.figure_size = float(figure_size[0]), float(figure_size[1])</pre>
<p>@@ -478,6 +478,8 @@</p>
<pre>                          'weight':'bold', 'size':24, 'color':'blue'})

        """</pre>
<p>+        from matplotlib.font_manager import FontProperties +</p>
<pre>         if font_dict is None:
font_dict = {}
         if 'color' in font_dict:</pre>
<p>@@ -589,6 +591,7 @@</p>
<pre>@validate_plot
def _send_zmq(self):</pre>
<p>+        from ._mpl_imports import FigureCanvasAgg</p>
<pre>         try:
# pre-IPython v1.0
from IPython.zmq.pylab.backend_inline import send_figure as display</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -22,11 +22,6 @@</p>
<pre>from distutils.version import LooseVersion
</pre>
<p>-from matplotlib.patches import Circle -from matplotlib.colors import colorConverter -from matplotlib import cm -from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar –</p>
<pre>from yt.config import \
    ytcfg
from yt.funcs import \</pre>
<p>@@ -561,6 +556,8 @@</p>
<pre>        self.edgecolors = edgecolors

    def __call__(self, plot):</pre>
<p>+        from matplotlib.colors import colorConverter +</p>
<pre>x0, x1 = plot.xlim
y0, y1 = plot.ylim
xx0, xx1 = plot._axes.get_xlim()</pre>
<p>@@ -1409,6 +1406,7 @@</p>
<pre>        self.factor = factor

    def __call__(self, plot):</pre>
<p>+        from matplotlib.patches import Circle</p>
<pre>data = plot.data
x0, x1 = plot.xlim
y0, y1 = plot.ylim</pre>
<p>@@ -2020,6 +2018,8 @@</p>
<pre>        self.text_args = text_args

    def __call__(self, plot):</pre>
<p>+        from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar +</p>
<pre># Callback only works for plots with axis ratios of 1
xsize = plot.xlim[1] - plot.xlim[0]
if plot.aspect != 1.0:</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/plot_window.py --- a/yt/visualization/plot_window.py +++ b/yt/visualization/plot_window.py @@ -21,7 +21,6 @@</p>
<pre>import sys

from distutils.version import LooseVersion</pre>
<p>-from matplotlib.mathtext import MathTextParser</p>
<pre>from numbers import Number

from .base_plot_types import ImagePlotMPL</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/profile_plotter.py --- a/yt/visualization/profile_plotter.py +++ b/yt/visualization/profile_plotter.py @@ -38,15 +38,15 @@</p>
<pre>from yt.utilities.exceptions import \
    YTNotInsideNotebook
from yt.utilities.logger import ytLogger as mylog</pre>
<p>-from . import _mpl_imports as mpl</p>
<pre>from yt.funcs import \
    ensure_list, \
    get_image_suffix, \
    get_ipython_api_version

def get_canvas(name):</pre>
<p>+    from . import _mpl_imports as mpl</p>
<pre>suffix = get_image_suffix(name)</pre>
<p>– +</p>
<pre>if suffix == '':
    suffix = '.png'
if suffix == ".png":</pre>
<p>@@ -65,7 +65,7 @@</p>
<pre>        super(FigureContainer, self).__init__()

    def __missing__(self, key):</pre>
<ul><li><p>figure = mpl.matplotlib.figure.Figure((10, 8))</p></li></ul>
<p>+        figure = matplotlib.figure.Figure((10, 8))</p>
<pre>        self[key] = figure
        return self[key]
</pre>
<p>@@ -309,6 +309,7 @@</p>
<pre>def _repr_html_(self):
    """Return an html representation of the plot object. Will display as a
    png for each WindowPlotMPL instance in self.plots"""</pre>
<p>+        from . import _mpl_imports as mpl</p>
<pre>ret = ''
unique = set(self.figures.values())
if len(unique) < len(self.figures):</pre>
<p>diff -r a412ed373902a47f9cd03556bc0064a1c83b1d7d -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e yt/visualization/volume_rendering/transfer_function_helper.py --- a/yt/visualization/volume_rendering/transfer_function_helper.py +++ b/yt/visualization/volume_rendering/transfer_function_helper.py @@ -18,8 +18,6 @@</p>
<pre>from yt.data_objects.profiles import create_profile
from yt.visualization.volume_rendering.transfer_functions import \
    ColorTransferFunction</pre>
<p>-from yt.visualization._mpl_imports import FigureCanvasAgg -from matplotlib.figure import Figure</p>
<pre>from yt.extern.six import BytesIO
import numpy as np
</pre>
<p>@@ -160,6 +158,8 @@</p>
<pre>        If fn is None, will return an image to an IPython notebook.

        """</pre>
<p>+        from yt.visualization._mpl_imports import FigureCanvasAgg +        from matplotlib.figure import Figure</p>
<pre>         if self.tf is None:
self.build_transfer_function()
         tf = self.tf</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/3e758589616e/">https://bitbucket.org/yt_analysis/yt/commits/3e758589616e/</a> Changeset:   3e758589616e Branch:      yt User:        ngoldbaum Date:        2016-04-25 18:43:48+00:00 Summary:     Fix errors detected by flake8 Affected #:  3 files</p>
<p>diff -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e -r 3e758589616ef58345a4ada26710b8c7a9f83478 yt/testing.py --- a/yt/testing.py +++ b/yt/testing.py @@ -20,7 +20,6 @@</p>
<pre>import numpy as np
import importlib
import os</pre>
<p>-import re</p>
<pre>import unittest
from yt.funcs import iterable
from yt.config import ytcfg</pre>
<p>@@ -33,7 +32,6 @@</p>
<pre>from numpy.testing import assert_string_equal  # NOQA
from numpy.testing import assert_array_almost_equal_nulp  # NOQA
from numpy.testing import assert_allclose, assert_raises  # NOQA</pre>
<p>-from unittest import TestCase</p>
<pre>from yt.convenience import load
from yt.units.yt_array import YTArray, YTQuantity
from yt.utilities.exceptions import YTUnitOperationError</pre>
<p>diff -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e -r 3e758589616ef58345a4ada26710b8c7a9f83478 yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -2312,6 +2312,7 @@</p>
<pre>        self.const_alpha = const_alpha

    def __call__(self, plot):</pre>
<p>+        from matplotlib import cm</p>
<pre>x0, x1 = plot.xlim
y0, y1 = plot.ylim
xx0, xx1 = plot._axes.get_xlim()</pre>
<p>diff -r f7881eb5c1eb4a10c6596d338100cd4ee3ccc36e -r 3e758589616ef58345a4ada26710b8c7a9f83478 yt/visualization/plot_window.py --- a/yt/visualization/plot_window.py +++ b/yt/visualization/plot_window.py @@ -686,6 +686,7 @@</p>
<pre>        return xc, yc

    def _setup_plots(self):</pre>
<p>+        from matplotlib.mathtext import MathTextParser</p>
<pre>         if self._plot_valid:
return
         if not self._data_valid:</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/b7e1465db7f8/">https://bitbucket.org/yt_analysis/yt/commits/b7e1465db7f8/</a> Changeset:   b7e1465db7f8 Branch:      yt User:        ngoldbaum Date:        2016-04-26 16:53:23+00:00 Summary:     Ensure matplotlib.figure namespace is imported in a few places Affected #:  3 files</p>
<p>diff -r 3e758589616ef58345a4ada26710b8c7a9f83478 -r b7e1465db7f84736f15f947b0c716794cee53dc2 yt/visualization/base_plot_types.py --- a/yt/visualization/base_plot_types.py +++ b/yt/visualization/base_plot_types.py @@ -55,6 +55,7 @@</p>
<pre>"""
def __init__(self, fsize, axrect, figure, axes):
    """Initialize PlotMPL class"""</pre>
<p>+        import matplotlib.figure</p>
<pre>from ._mpl_imports import FigureCanvasAgg
self._plot_valid = True
if figure is None:</pre>
<p>@@ -317,6 +318,7 @@</p>
<pre>can be instructure, and is encouraged to see how to generate more
complicated or more specific sets of multiplots for your own purposes.
"""</pre>
<p>+    import matplotlib.figure</p>
<pre>hf, wf = 1.0/ny, 1.0/nx
fudge_x = fudge_y = 1.0
if colorbar is None:</pre>
<p>diff -r 3e758589616ef58345a4ada26710b8c7a9f83478 -r b7e1465db7f84736f15f947b0c716794cee53dc2 yt/visualization/image_writer.py --- a/yt/visualization/image_writer.py +++ b/yt/visualization/image_writer.py @@ -368,7 +368,8 @@</p>
<pre>"""
if cmap_name is None:
    cmap_name = ytcfg.get("yt", "default_colormap")</pre>
<ul><li><p>import matplotlib</p></li></ul>
<p>+    import matplotlib.figure +    import matplotlib.colors</p>
<pre>    from ._mpl_imports import FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS

    # If this is rendered as log, then apply now.</pre>
<p>diff -r 3e758589616ef58345a4ada26710b8c7a9f83478 -r b7e1465db7f84736f15f947b0c716794cee53dc2 yt/visualization/profile_plotter.py --- a/yt/visualization/profile_plotter.py +++ b/yt/visualization/profile_plotter.py @@ -65,7 +65,8 @@</p>
<pre>        super(FigureContainer, self).__init__()

    def __missing__(self, key):</pre>
<ul><li><p>figure = matplotlib.figure.Figure((10, 8))</p></li></ul>
<p>+        from matplotlib.figure import Figure +        figure = Figure((10, 8))</p>
<pre>        self[key] = figure
        return self[key]
</pre>
<p><a href="https://bitbucket.org/yt_analysis/yt/commits/21cedef7066b/">https://bitbucket.org/yt_analysis/yt/commits/21cedef7066b/</a> Changeset:   21cedef7066b Branch:      yt User:        xarthisius Date:        2016-05-04 18:07:21+00:00 Summary:     Merged in ngoldbaum/yt (pull request #2140)</p>
<p>Speed up top-level yt import Affected #:  17 files</p>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/frontends/fits/misc.py --- a/yt/frontends/fits/misc.py +++ b/yt/frontends/fits/misc.py @@ -16,7 +16,6 @@</p>
<pre>from yt.fields.derived_field import ValidateSpatial
from yt.funcs import mylog
from yt.utilities.on_demand_imports import _astropy</pre>
<p>-from yt.visualization._mpl_imports import FigureCanvasAgg</p>
<pre>from yt.units.yt_array import YTQuantity, YTArray
from yt.utilities.fits_image import FITSImageData
if PY3:</pre>
<p>@@ -258,6 +257,7 @@</p>
<pre>        self.pw.save(name=name, mpl_kwargs=mpl_kwargs)

    def _repr_html_(self):</pre>
<p>+        from yt.visualization._mpl_imports import FigureCanvasAgg</p>
<pre>         ret = ''
         for k, v in self.plots.items():
canvas = FigureCanvasAgg(v)</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/frontends/http_stream/data_structures.py --- a/yt/frontends/http_stream/data_structures.py +++ b/yt/frontends/http_stream/data_structures.py @@ -15,6 +15,7 @@</p>
<pre># The full license is in the file COPYING.txt, distributed with this software.
#-----------------------------------------------------------------------------
</pre>
<p>+import json</p>
<pre>import numpy as np
import time
</pre>
<p>@@ -24,15 +25,11 @@</p>
<pre>    ParticleDataset
from yt.frontends.sph.fields import \
    SPHFieldInfo</pre>
<p>+from yt.funcs import \ +    get_requests</p>
<pre>from yt.geometry.particle_geometry_handler import \
    ParticleIndex
</pre>
<p>-try:</p>
<ul><li><p>import requests</p></li>
<li><p>import json</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>requests = None</p></li></ul>
<p>–</p>
<pre>class HTTPParticleFile(ParticleFile):
    pass
</pre>
<p>@@ -49,8 +46,9 @@</p>
<pre>dataset_type = "http_particle_stream",
n_ref = 64, over_refine_factor=1,
unit_system="cgs"):</pre>
<ul><li><p>if requests is None:</p></li>
<li><p>raise RuntimeError</p></li></ul>
<p>+        if get_requests() is None: +            raise ImportError( +                “This functionality depends on the requests package”)</p>
<pre>self.base_url = base_url
self.n_ref = n_ref
self.over_refine_factor = over_refine_factor</pre>
<p>@@ -66,6 +64,7 @@</p>
<pre>        self.parameters["HydroMethod"] = "sph"

        # Here's where we're going to grab the JSON index file</pre>
<p>+        requests = get_requests()</p>
<pre>         hreq = requests.get(self.base_url + "/yt_index.json")
         if hreq.status_code != 200:
raise RuntimeError</pre>
<p>@@ -108,6 +107,9 @@</p>
<pre>     def _is_valid(self, *args, **kwargs):
         if not args[0].startswith("http://"):
return False</pre>
<p>+        requests = get_requests() +        if requests is None: +            return False</p>
<pre>         hreq = requests.get(args[0] + "/yt_index.json")
         if hreq.status_code == 200:
return True</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/frontends/http_stream/io.py --- a/yt/frontends/http_stream/io.py +++ b/yt/frontends/http_stream/io.py @@ -18,24 +18,21 @@</p>
<pre>import numpy as np

from yt.funcs import \</pre>
<p>+    get_requests, \</p>
<pre>    mylog
from yt.utilities.io_handler import \
    BaseIOHandler
from yt.utilities.lib.geometry_utils import \
    compute_morton
</pre>
<p>-try:</p>
<ul><li><p>import requests</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>requests = None</p></li></ul>
<p>–</p>
<pre>class IOHandlerHTTPStream(BaseIOHandler):
    _dataset_type = "http_particle_stream"
    _vector_fields = ("Coordinates", "Velocity", "Velocities")

    def __init__(self, ds):</pre>
<ul><li><p>if requests is None:</p></li>
<li><p>raise RuntimeError</p></li></ul>
<p>+        if get_requests() is None: +            raise ImportError( +                “This functionality depends on the requests package”)</p>
<pre>self._url = ds.base_url
# This should eventually manage the IO and cache it
self.total_bytes = 0</pre>
<p>@@ -47,6 +44,7 @@</p>
<pre>         s = "%s/%s/%s/%s" % (self._url,
data_file.file_id, ftype, fname)
         mylog.info("Loading URL %s", s)</pre>
<p>+        requests = get_requests()</p>
<pre>         resp = requests.get(s)
         if resp.status_code != 200:
raise RuntimeError</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/frontends/sdf/data_structures.py --- a/yt/frontends/sdf/data_structures.py +++ b/yt/frontends/sdf/data_structures.py @@ -27,6 +27,8 @@</p>
<pre>    ParticleIndex
from yt.data_objects.static_output import \
    Dataset, ParticleFile</pre>
<p>+from yt.funcs import \ +    get_requests</p>
<pre>from .fields import \
    SDFFieldInfo
from yt.utilities.sdf import \</pre>
<p>@@ -34,11 +36,6 @@</p>
<pre>    SDFIndex,\
    HTTPSDFRead
</pre>
<p>-try:</p>
<ul><li><p>import requests</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>requests = None</p></li></ul>
<p>–</p>
<pre>@contextlib.contextmanager
def safeopen(*args, **kwargs):
    if sys.version[0] != '3':</pre>
<p>@@ -195,7 +192,9 @@</p>
<pre>def _is_valid(cls, *args, **kwargs):
    sdf_header = kwargs.get('sdf_header', args[0])
    if sdf_header.startswith("http"):</pre>
<ul><li><p>if requests is None: return False</p></li></ul>
<p>+            requests = get_requests() +            if requests is None: +                return False</p>
<pre>hreq = requests.get(sdf_header, stream=True)
if hreq.status_code != 200: return False
# Grab a whole 4k page.</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/funcs.py --- a/yt/funcs.py +++ b/yt/funcs.py @@ -953,3 +953,10 @@</p>
<pre>         raise RuntimeError(
"Please install palettable to use colorbrewer colormaps")
     return bmap.get_mpl_colormap(N=cmap[2])</pre>
<p>+ +def get_requests(): +    try: +        import requests +    except ImportError: +        requests = None +    return requests</p>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/testing.py --- a/yt/testing.py +++ b/yt/testing.py @@ -20,6 +20,7 @@</p>
<pre>import numpy as np
import importlib
import os</pre>
<p>+import unittest</p>
<pre>from yt.funcs import iterable
from yt.config import ytcfg
# we import this in a weird way from numpy.testing to avoid triggering</pre>
<p>@@ -31,16 +32,22 @@</p>
<pre>from numpy.testing import assert_string_equal  # NOQA
from numpy.testing import assert_array_almost_equal_nulp  # NOQA
from numpy.testing import assert_allclose, assert_raises  # NOQA</pre>
<p>-try:</p>
<ul><li><p>from nose.tools import assert_true, assert_less_equal  # NOQA</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p># This means nose isn't installed, so the tests can't run and it's ok</p></li>
<li><p># to not import these functions</p></li>
<li><p>pass</p></li></ul>
<pre>from yt.convenience import load
from yt.units.yt_array import YTArray, YTQuantity
from yt.utilities.exceptions import YTUnitOperationError
</pre>
<p>+# Expose assert_true and assert_less_equal from unittest.TestCase +# this is adopted from nose. Doing this here allows us to avoid importing +# nose at the top level. +class _Dummy(unittest.TestCase): +    def nop(): +        pass +_t = _Dummy('nop') + +assert_true = getattr(_t, ‘assertTrue’) +assert_less_equal = getattr(_t, ‘assertLessEqual’) + +</p>
<pre>def assert_rel_equal(a1, a2, decimals, err_msg='', verbose=True):
    # We have nan checks in here because occasionally we have fields that get
    # weighted without non-zero weights.  I'm looking at you, particle fields!</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/utilities/sdf.py --- a/yt/utilities/sdf.py +++ b/yt/utilities/sdf.py @@ -2,13 +2,18 @@</p>
<pre>from yt.extern.six.moves import cStringIO
import os
import numpy as np</pre>
<p>-try:</p>
<ul><li><p>from thingking.httpmmap import HTTPArray</p></li>
<li><p>from thingking.arbitrary_page import PageCacheURL</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>HTTPArray = PageCacheURL = None</p></li></ul>
<p>+</p>
<pre>from yt.funcs import mylog
</pre>
<p>+def get_thingking_deps(): +    try: +        from thingking.httpmmap import HTTPArray +        from thingking.arbitrary_page import PageCacheURL +    except ImportError: +        raise ImportError( +            “This functionality requires the thingking package to be installed”) +    return HTTPArray, PageCacheURL +</p>
<pre>_types = {
    'int16_t': 'int16',
    'uint16_t': 'uint16',</pre>
<p>@@ -216,8 +221,8 @@</p>
<pre>def __init__(self, *args, **kwargs):
    super(HTTPDataStruct, self).__init__(*args, **kwargs)</pre>
<ul><li><p>if None in (PageCacheURL, HTTPArray):</p></li>
<li><p>raise ImportError("'thingking' is required for loading of remote HTTP data.")</p></li></ul>
<p>+        HTTPArray, PageCacheURL = get_thingking_deps() +        self.HTTPArray = HTTPArray</p>
<pre>        self.pcu = PageCacheURL(self.filename)

    def set_offset(self, offset):</pre>
<p>@@ -232,7 +237,7 @@</p>
<pre>def build_memmap(self):
    assert(self.size != -1)
    mylog.info('Building memmap with offset: %i and size %i' % (self._offset, self.size))</pre>
<ul><li><p>self.handle = HTTPArray(self.filename, dtype=self.dtype,</p></li></ul>
<p>+        self.handle = self.HTTPArray(self.filename, dtype=self.dtype,</p>
<pre>            shape=self.size, offset=self._offset)
         for k in self.dtype.names:
self.data[k] = RedirectArray(self.handle, k)</pre>
<p>@@ -457,14 +462,14 @@</p>
<pre>    _data_struct = HTTPDataStruct

    def __init__(self, *args, **kwargs):</pre>
<ul><li><p>if None in (PageCacheURL, HTTPArray):</p></li>
<li><p>raise ImportError("thingking")</p></li></ul>
<p>+        HTTPArray, _ = get_thingking_deps() +        self.HTTPArray = HTTPArray</p>
<pre>        super(HTTPSDFRead, self).__init__(*args, **kwargs)

    def parse_header(self):
        """docstring for parse_header"""
        # Pre-process</pre>
<ul><li><p>ascfile = HTTPArray(self.header)</p></li></ul>
<p>+        ascfile = self.HTTPArray(self.header)</p>
<pre>max_header_size = 1024*1024
lines = cStringIO(ascfile[:max_header_size].data[:])
while True:</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/_mpl_imports.py --- a/yt/visualization/_mpl_imports.py +++ b/yt/visualization/_mpl_imports.py @@ -1,16 +1,6 @@</p>
<pre>import matplotlib
matplotlib.rc('contour', negative_linestyle='solid')
</pre>
<p>-import matplotlib.image -import matplotlib.ticker -import matplotlib.axes -import matplotlib.figure -import matplotlib._image -import matplotlib.colors -import matplotlib.colorbar -import matplotlib.cm -import matplotlib.collections –</p>
<pre>from matplotlib.backends.backend_agg import \
    FigureCanvasAgg
</pre>
<p>@@ -19,33 +9,3 @@</p>
<pre>from matplotlib.backends.backend_ps import \
    FigureCanvasPS</pre>
<p>– -# Now we provide some convenience functions to get information about plots. -# With Matplotlib 0.98.x, the ‘transforms’ branch broke backwards -# compatibility.  Despite that, the various packagers are plowing ahead with -# packaging 0.98.x with new distributions of python software.  So I guess -# we have to support it. – -_compatibility_functions = ["mpl_get_bounds","mpl_notify"] – -_mpl98_mpl_get_bounds = lambda bbox: bbox.bounds -_mpl9x_mpl_get_bounds = lambda bbox: bbox.get_bounds() -_mpl98_mpl_notify = lambda im,cb: cb.update_bruteforce(im) -_mpl9x_mpl_notify = lambda im,cb: cb.notify(im) – -# This next function hurts, because it relies on the fact that we're -# only differentiating between 0.9[01] and 0.98. And if happens to be -# 1.0, or any version with only 3 values, this should catch it. – -try:</p>
<ul><li><p>_mpl_version = float(matplotlib.__version__[:4])</p></li></ul>
<p>-except:</p>
<ul><li><p>_mpl_version = float(matplotlib.__version__[:3])</p></li></ul>
<p>– -if _mpl_version < 0.98:</p>
<ul><li><p>_prefix = ‘_mpl9x’</p></li></ul>
<p>-else:</p>
<ul><li><p>_prefix = ‘_mpl98’</p></li></ul>
<p>– -for fn in _compatibility_functions:</p>
<ul><li><p>exec("%s = %s_%s" % (fn, _prefix, fn))</p></li></ul>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/base_plot_types.py --- a/yt/visualization/base_plot_types.py +++ b/yt/visualization/base_plot_types.py @@ -15,8 +15,6 @@</p>
<pre>#-----------------------------------------------------------------------------
from io import BytesIO
import matplotlib</pre>
<p>-from ._mpl_imports import \</p>
<ul><li><p>FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS</p></li></ul>
<pre>from yt.funcs import \
    get_image_suffix, \
    mylog, \</pre>
<p>@@ -57,6 +55,8 @@</p>
<pre>"""
def __init__(self, fsize, axrect, figure, axes):
    """Initialize PlotMPL class"""</pre>
<p>+        import matplotlib.figure +        from ._mpl_imports import FigureCanvasAgg</p>
<pre>         self._plot_valid = True
         if figure is None:
self.figure = matplotlib.figure.Figure(figsize=fsize, frameon=True)</pre>
<p>@@ -73,6 +73,8 @@</p>
<pre>def save(self, name, mpl_kwargs=None, canvas=None):
    """Choose backend and save image to disk"""</pre>
<p>+        from ._mpl_imports import \ +            FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS</p>
<pre>         if mpl_kwargs is None:
mpl_kwargs = {}
         if 'papertype' not in mpl_kwargs:</pre>
<p>@@ -144,6 +146,7 @@</p>
<pre>            self.cb = self.figure.colorbar(self.image, self.cax)

    def _repr_png_(self):</pre>
<p>+        from ._mpl_imports import FigureCanvasAgg</p>
<pre>canvas = FigureCanvasAgg(self.figure)
f = BytesIO()
canvas.print_figure(f)</pre>
<p>@@ -315,6 +318,7 @@</p>
<pre>can be instructure, and is encouraged to see how to generate more
complicated or more specific sets of multiplots for your own purposes.
"""</pre>
<p>+    import matplotlib.figure</p>
<pre>hf, wf = 1.0/ny, 1.0/nx
fudge_x = fudge_y = 1.0
if colorbar is None:</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/eps_writer.py --- a/yt/visualization/eps_writer.py +++ b/yt/visualization/eps_writer.py @@ -17,7 +17,6 @@</p>
<pre>import numpy as np
from matplotlib import cm
import matplotlib.pyplot as plt</pre>
<p>-from ._mpl_imports import FigureCanvasAgg</p>
<pre>from yt.config import \
    ytcfg</pre>
<p>@@ -509,7 +508,8 @@</p>
<pre>For best results, set use_colorbar=False when creating the yt
image.
"""</pre>
<p>– +        from ._mpl_imports import FigureCanvasAgg +</p>
<pre># We need to remove the colorbar (if necessary), remove the
# axes, and resize the figure to span the entire figure
force_square = False</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/image_writer.py --- a/yt/visualization/image_writer.py +++ b/yt/visualization/image_writer.py @@ -368,7 +368,8 @@</p>
<pre>"""
if cmap_name is None:
    cmap_name = ytcfg.get("yt", "default_colormap")</pre>
<ul><li><p>import matplotlib</p></li></ul>
<p>+    import matplotlib.figure +    import matplotlib.colors</p>
<pre>    from ._mpl_imports import FigureCanvasAgg, FigureCanvasPdf, FigureCanvasPS

    # If this is rendered as log, then apply now.</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/plot_container.py --- a/yt/visualization/plot_container.py +++ b/yt/visualization/plot_container.py @@ -23,9 +23,7 @@</p>
<pre>from collections import defaultdict
from functools import wraps</pre>
<p>-from matplotlib.font_manager import FontProperties</p>
<p>-from ._mpl_imports import FigureCanvasAgg</p>
<pre>from .tick_locators import LogLocator, LinearLocator

from yt.config import \</pre>
<p>@@ -184,6 +182,8 @@</p>
<pre>    _colorbar_valid = False

    def __init__(self, data_source, figure_size, fontsize):</pre>
<p>+        from matplotlib.font_manager import FontProperties +</p>
<pre>         self.data_source = data_source
         if iterable(figure_size):
self.figure_size = float(figure_size[0]), float(figure_size[1])</pre>
<p>@@ -478,6 +478,8 @@</p>
<pre>                          'weight':'bold', 'size':24, 'color':'blue'})

        """</pre>
<p>+        from matplotlib.font_manager import FontProperties +</p>
<pre>         if font_dict is None:
font_dict = {}
         if 'color' in font_dict:</pre>
<p>@@ -589,6 +591,7 @@</p>
<pre>@validate_plot
def _send_zmq(self):</pre>
<p>+        from ._mpl_imports import FigureCanvasAgg</p>
<pre>         try:
# pre-IPython v1.0
from IPython.zmq.pylab.backend_inline import send_figure as display</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/plot_modifications.py --- a/yt/visualization/plot_modifications.py +++ b/yt/visualization/plot_modifications.py @@ -22,11 +22,6 @@</p>
<pre>from distutils.version import LooseVersion
</pre>
<p>-from matplotlib.patches import Circle -from matplotlib.colors import colorConverter -from matplotlib import cm -from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar –</p>
<pre>from yt.config import \
    ytcfg
from yt.funcs import \</pre>
<p>@@ -561,6 +556,8 @@</p>
<pre>        self.edgecolors = edgecolors

    def __call__(self, plot):</pre>
<p>+        from matplotlib.colors import colorConverter +</p>
<pre>x0, x1 = plot.xlim
y0, y1 = plot.ylim
xx0, xx1 = plot._axes.get_xlim()</pre>
<p>@@ -1409,6 +1406,7 @@</p>
<pre>        self.factor = factor

    def __call__(self, plot):</pre>
<p>+        from matplotlib.patches import Circle</p>
<pre>data = plot.data
x0, x1 = plot.xlim
y0, y1 = plot.ylim</pre>
<p>@@ -2020,6 +2018,8 @@</p>
<pre>        self.text_args = text_args

    def __call__(self, plot):</pre>
<p>+        from mpl_toolkits.axes_grid1.anchored_artists import AnchoredSizeBar +</p>
<pre># Callback only works for plots with axis ratios of 1
xsize = plot.xlim[1] - plot.xlim[0]
if plot.aspect != 1.0:</pre>
<p>@@ -2312,6 +2312,7 @@</p>
<pre>        self.const_alpha = const_alpha

    def __call__(self, plot):</pre>
<p>+        from matplotlib import cm</p>
<pre>x0, x1 = plot.xlim
y0, y1 = plot.ylim
xx0, xx1 = plot._axes.get_xlim()</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/plot_window.py --- a/yt/visualization/plot_window.py +++ b/yt/visualization/plot_window.py @@ -21,7 +21,6 @@</p>
<pre>import sys

from distutils.version import LooseVersion</pre>
<p>-from matplotlib.mathtext import MathTextParser</p>
<pre>from numbers import Number

from .base_plot_types import ImagePlotMPL</pre>
<p>@@ -687,6 +686,7 @@</p>
<pre>        return xc, yc

    def _setup_plots(self):</pre>
<p>+        from matplotlib.mathtext import MathTextParser</p>
<pre>         if self._plot_valid:
return
         if not self._data_valid:</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/profile_plotter.py --- a/yt/visualization/profile_plotter.py +++ b/yt/visualization/profile_plotter.py @@ -38,15 +38,15 @@</p>
<pre>from yt.utilities.exceptions import \
    YTNotInsideNotebook
from yt.utilities.logger import ytLogger as mylog</pre>
<p>-from . import _mpl_imports as mpl</p>
<pre>from yt.funcs import \
    ensure_list, \
    get_image_suffix, \
    get_ipython_api_version

def get_canvas(name):</pre>
<p>+    from . import _mpl_imports as mpl</p>
<pre>suffix = get_image_suffix(name)</pre>
<p>– +</p>
<pre>if suffix == '':
    suffix = '.png'
if suffix == ".png":</pre>
<p>@@ -65,7 +65,8 @@</p>
<pre>        super(FigureContainer, self).__init__()

    def __missing__(self, key):</pre>
<ul><li><p>figure = mpl.matplotlib.figure.Figure((10, 8))</p></li></ul>
<p>+        from matplotlib.figure import Figure +        figure = Figure((10, 8))</p>
<pre>        self[key] = figure
        return self[key]
</pre>
<p>@@ -314,6 +315,7 @@</p>
<pre>def _repr_html_(self):
    """Return an html representation of the plot object. Will display as a
    png for each WindowPlotMPL instance in self.plots"""</pre>
<p>+        from . import _mpl_imports as mpl</p>
<pre>ret = ''
unique = set(self.figures.values())
if len(unique) < len(self.figures):</pre>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/volume_rendering/interactive_vr_helpers.py --- a/yt/visualization/volume_rendering/interactive_vr_helpers.py +++ b/yt/visualization/volume_rendering/interactive_vr_helpers.py @@ -17,7 +17,6 @@</p>
<pre>from yt.funcs import mylog
from yt.data_objects.static_output import Dataset
from yt.utilities.exceptions import YTSceneFieldNotFound</pre>
<p>-from yt.utilities.on_demand_imports import NotAModule</p>
<pre>def _render_opengl(data_source, field=None, window_size=None, cam_position=None,
                   cam_focus=None):</pre>
<p>@@ -52,6 +51,13 @@</p>
<pre>    '''
</pre>
<p>+    try: +        import cyglfw3  # NOQA +        import OpenGL.GL  # NOQA +    except ImportError: +        raise ImportError("This functionality requires the cyglfw3 and PyOpenGL " +                          “packages to be installed.”) +</p>
<pre>    from .interactive_vr import SceneGraph, BlockCollection, TrackballCamera
    from .interactive_loop import RenderingContext
</pre>
<p>@@ -87,9 +93,4 @@</p>
<pre>    rc.start_loop(scene, c)

</pre>
<p>-try:</p>
<ul><li><p>import cyglfw3 as glfw  # NOQA</p></li>
<li><p>import OpenGL.GL as GL  # NOQA</p></li>
<li><p>interactive_render = _render_opengl</p></li></ul>
<p>-except ImportError:</p>
<ul><li><p>interactive_render = NotAModule("opengl/cyglfw3")</p></li></ul>
<p>+interactive_render = _render_opengl</p>
<p>diff -r dedf4c47220e9551cf8ce24f10c9259da92f4361 -r 21cedef7066b43a139336890244be2c47f5af0fa yt/visualization/volume_rendering/transfer_function_helper.py --- a/yt/visualization/volume_rendering/transfer_function_helper.py +++ b/yt/visualization/volume_rendering/transfer_function_helper.py @@ -18,8 +18,6 @@</p>
<pre>from yt.data_objects.profiles import create_profile
from yt.visualization.volume_rendering.transfer_functions import \
    ColorTransferFunction</pre>
<p>-from yt.visualization._mpl_imports import FigureCanvasAgg -from matplotlib.figure import Figure</p>
<pre>from yt.extern.six import BytesIO
import numpy as np
</pre>
<p>@@ -160,6 +158,8 @@</p>
<pre>        If fn is None, will return an image to an IPython notebook.

        """</pre>
<p>+        from yt.visualization._mpl_imports import FigureCanvasAgg +        from matplotlib.figure import Figure</p>
<pre>         if self.tf is None:
self.build_transfer_function()
         tf = self.tf</pre>
<p>Repository URL: <a href="https://bitbucket.org/yt_analysis/yt/">https://bitbucket.org/yt_analysis/yt/</a></p>
<p>—</p>
<p>This is a commit notification from bitbucket.org. You are receiving this because you have the service enabled, addressing the recipient of this email.</p>

<img src="http://link.bitbucket.org/wf/open?upn=ll4ctv0L-2ByeRZFC1LslHcg6aJmnQ70VruLbmeLQr27CpRj4Us3KN02yKXaFrd8fPKe6BUWUR73o0eDYrd527iMqke8SMOdwi-2F-2B7A3fm47LT62-2FWDUVKfGaBCu11aCB2uLgOM8GucR-2BcfQ7BFSpxvbdGJ77Qb-2B7FO1UU1y95EvmEONK821sb2V-2B-2B-2F0XOYjLG4MlOrVYe-2FuKSQoZZbatmGPKoUPjMo-2FTbfuj0VTRqXt1w-3D" alt="" width="1" height="1" border="0" style="height:1px !important;width:1px !important;border-width:0 !important;margin-top:0 !important;margin-bottom:0 !important;margin-right:0 !important;margin-left:0 !important;padding-top:0 !important;padding-bottom:0 !important;padding-right:0 !important;padding-left:0 !important;"/>
</body></html>