From 8584b91cc00eb7a080055b43965c2558251f2c41 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Thu, 3 Nov 2016 23:33:20 +0100 Subject: [PATCH 1/9] fixes https://github.com/pydata/xarray/issues/781 --- doc/whats-new.rst | 5 +++++ xarray/plot/plot.py | 17 +++++++++++------ xarray/test/test_plot.py | 10 ++++------ 3 files changed, 20 insertions(+), 12 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 0d28346d740..9bd1b85af60 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -108,6 +108,11 @@ Bug fixes - ``Dataset.concat()`` now preserves variables order (:issue:`1027`). By `Fabien Maussion `_. +- Fixed a regression with pcolormesh (:issue:`1027`). A new + ``infer_interval_breaks`` keyword gives control on whether the interval + breaks should be computed or not. + By `Fabien Maussion `_. + .. _whats-new.0.8.2: v0.8.2 (18 August 2016) diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index 11a32e9f85e..5d332ae1c76 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -316,6 +316,10 @@ def _plot2d(plotfunc): provided, extend is inferred from vmin, vmax and the data limits. levels : int or list-like object, optional Split the colormap (cmap) into discrete color intervals. + infer_interval_breaks : bool, optional + Only applies to pcolormesh. If True, the coordinate intervals are + passed to pcolormesh (the default). If False, the original coordinates + are used (this can be useful for certain map projections). subplot_kws : dict, optional Dictionary of keyword arguments for matplotlib subplots. Only applies to FacetGrid plotting. @@ -341,8 +345,9 @@ def newplotfunc(darray, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, add_colorbar=None, add_labels=True, vmin=None, vmax=None, cmap=None, center=None, robust=False, extend=None, - levels=None, colors=None, subplot_kws=None, - cbar_ax=None, cbar_kwargs=None, **kwargs): + levels=None, infer_interval_breaks=True, colors=None, + subplot_kws=None, cbar_ax=None, cbar_kwargs=None, + **kwargs): # All 2d plots in xarray share this function signature. # Method signature below should be consistent. @@ -456,8 +461,8 @@ def plotmethod(_PlotMethods_obj, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, add_colorbar=None, add_labels=True, vmin=None, vmax=None, cmap=None, colors=None, center=None, robust=False, - extend=None, levels=None, subplot_kws=None, - cbar_ax=None, cbar_kwargs=None, **kwargs): + extend=None, levels=None, infer_interval_breaks=True, + subplot_kws=None, cbar_ax=None, cbar_kwargs=None, **kwargs): """ The method should have the same signature as the function. @@ -555,14 +560,14 @@ def _infer_interval_breaks(coord): @_plot2d -def pcolormesh(x, y, z, ax, **kwargs): +def pcolormesh(x, y, z, ax, infer_interval_breaks=True, **kwargs): """ Pseudocolor plot of 2d DataArray Wraps matplotlib.pyplot.pcolormesh """ - if not hasattr(ax, 'projection'): + if infer_interval_breaks: x = _infer_interval_breaks(x) y = _infer_interval_breaks(y) diff --git a/xarray/test/test_plot.py b/xarray/test/test_plot.py index 4e812d2b602..c523645a901 100644 --- a/xarray/test/test_plot.py +++ b/xarray/test/test_plot.py @@ -851,14 +851,12 @@ def test_2d_coord_names(self): self.assertEqual('x2d', ax.get_xlabel()) self.assertEqual('y2d', ax.get_ylabel()) - def test_dont_infer_interval_breaks_for_cartopy(self): - # Regression for GH 781 + def test_infer_interval_breaks_for_cartopy(self): + # GH 781 ax = plt.gca() - # Simulate a Cartopy Axis - setattr(ax, 'projection', True) - artist = self.plotmethod(x='x2d', y='y2d', ax=ax) + artist = self.plotmethod(x='x2d', y='y2d', ax=ax, + infer_interval_breaks=False) self.assertTrue(isinstance(artist, mpl.collections.QuadMesh)) - # Let cartopy handle the axis limits and artist size self.assertTrue(artist.get_array().size <= self.darray.size) From 182280a22bfb7cc18240c63770ac62cb8f176924 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Thu, 3 Nov 2016 23:44:16 +0100 Subject: [PATCH 2/9] typo --- doc/whats-new.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 9bd1b85af60..a91a0a0b3f9 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -108,7 +108,7 @@ Bug fixes - ``Dataset.concat()`` now preserves variables order (:issue:`1027`). By `Fabien Maussion `_. -- Fixed a regression with pcolormesh (:issue:`1027`). A new +- Fixed a regression with pcolormesh (:issue:`781`). A new ``infer_interval_breaks`` keyword gives control on whether the interval breaks should be computed or not. By `Fabien Maussion `_. From f8953fd6a455ffc4775eed2c566b34df8e87a9c0 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Fri, 4 Nov 2016 10:28:56 +0100 Subject: [PATCH 3/9] rename keyword --- doc/whats-new.rst | 4 ++-- xarray/plot/plot.py | 10 +++++----- xarray/test/test_plot.py | 2 +- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/doc/whats-new.rst b/doc/whats-new.rst index a91a0a0b3f9..15a0b8eb17d 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -109,8 +109,8 @@ Bug fixes By `Fabien Maussion `_. - Fixed a regression with pcolormesh (:issue:`781`). A new - ``infer_interval_breaks`` keyword gives control on whether the interval - breaks should be computed or not. + ``infer_intervals`` keyword gives control on whether the cell intervals + should be computed or not. By `Fabien Maussion `_. .. _whats-new.0.8.2: diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index 5d332ae1c76..29b9eb98a4d 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -316,7 +316,7 @@ def _plot2d(plotfunc): provided, extend is inferred from vmin, vmax and the data limits. levels : int or list-like object, optional Split the colormap (cmap) into discrete color intervals. - infer_interval_breaks : bool, optional + infer_intervals : bool, optional Only applies to pcolormesh. If True, the coordinate intervals are passed to pcolormesh (the default). If False, the original coordinates are used (this can be useful for certain map projections). @@ -345,7 +345,7 @@ def newplotfunc(darray, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, add_colorbar=None, add_labels=True, vmin=None, vmax=None, cmap=None, center=None, robust=False, extend=None, - levels=None, infer_interval_breaks=True, colors=None, + levels=None, infer_intervals=True, colors=None, subplot_kws=None, cbar_ax=None, cbar_kwargs=None, **kwargs): # All 2d plots in xarray share this function signature. @@ -461,7 +461,7 @@ def plotmethod(_PlotMethods_obj, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, add_colorbar=None, add_labels=True, vmin=None, vmax=None, cmap=None, colors=None, center=None, robust=False, - extend=None, levels=None, infer_interval_breaks=True, + extend=None, levels=None, infer_intervals=True, subplot_kws=None, cbar_ax=None, cbar_kwargs=None, **kwargs): """ The method should have the same signature as the function. @@ -560,14 +560,14 @@ def _infer_interval_breaks(coord): @_plot2d -def pcolormesh(x, y, z, ax, infer_interval_breaks=True, **kwargs): +def pcolormesh(x, y, z, ax, infer_intervals=True, **kwargs): """ Pseudocolor plot of 2d DataArray Wraps matplotlib.pyplot.pcolormesh """ - if infer_interval_breaks: + if infer_intervals: x = _infer_interval_breaks(x) y = _infer_interval_breaks(y) diff --git a/xarray/test/test_plot.py b/xarray/test/test_plot.py index c523645a901..2d57b2d073e 100644 --- a/xarray/test/test_plot.py +++ b/xarray/test/test_plot.py @@ -855,7 +855,7 @@ def test_infer_interval_breaks_for_cartopy(self): # GH 781 ax = plt.gca() artist = self.plotmethod(x='x2d', y='y2d', ax=ax, - infer_interval_breaks=False) + infer_intervals=False) self.assertTrue(isinstance(artist, mpl.collections.QuadMesh)) self.assertTrue(artist.get_array().size <= self.darray.size) From 26dc7361f66b944991f18d9636046e90813e67e5 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Fri, 4 Nov 2016 10:58:22 +0100 Subject: [PATCH 4/9] the kwargs should also be passed over now --- xarray/plot/plot.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index 29b9eb98a4d..050cc9c364e 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -421,6 +421,9 @@ def newplotfunc(darray, x=None, y=None, ax=None, row=None, col=None, kwargs['extend'] = cmap_params['extend'] kwargs['levels'] = cmap_params['levels'] + if 'pcolormesh' == plotfunc.__name__: + kwargs['infer_intervals'] = infer_intervals + # This allows the user to pass in a custom norm coming via kwargs kwargs.setdefault('norm', cmap_params['norm']) From a40ab58911bfc58d475e5b9608376491f00faf2f Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Mon, 7 Nov 2016 19:21:27 +0100 Subject: [PATCH 5/9] infer 2d coords, new chapter in docs --- doc/plotting.rst | 49 +++++++++++++++++++++++++++++++++++++ doc/whats-new.rst | 2 +- xarray/plot/plot.py | 53 +++++++++++++++++++++++++++++++--------- xarray/test/test_plot.py | 11 +++++++++ 4 files changed, 102 insertions(+), 13 deletions(-) diff --git a/doc/plotting.rst b/doc/plotting.rst index 7ecef12e763..d44fbada060 100644 --- a/doc/plotting.rst +++ b/doc/plotting.rst @@ -522,3 +522,52 @@ the values on the y axis are decreasing with -0.5 on the top. This is because the pixels are centered over their coordinates, and the axis labels and ranges correspond to the values of the coordinates. + +Irregular coordinates +~~~~~~~~~~~~~~~~~~~~~ + +You can plot irregular grids using xarray, but you'll have to tell the plot +function to use these coordinates instead: + +.. ipython:: python + + lon, lat = np.meshgrid(np.linspace(-20, 20, 5), np.linspace(0, 30, 4)) + lon += lat/10 + lat += lon/10 + da = xr.DataArray(np.arange(20).reshape(4, 5), dims=['y', 'x'], + coords = {'lat': (('y', 'x'), lat), + 'lon': (('y', 'x'), lon)}) + + @savefig plotting_example_2d_irreg.png width=4in + da.plot.pcolormesh('lon', 'lat'); + +Note that in this case, xarray still follows the pixel centered convention. +This might be undesirable in some cases (e.g. :issue:`781`), and this is why +the default is to not follow this convention when plotting on a map: + +.. ipython:: python + + import cartopy.crs as ccrs + ax = plt.subplot(projection=ccrs.PlateCarree()); + da.plot.pcolormesh('lon', 'lat', ax=ax); + ax.scatter(lon, lat, transform=ccrs.PlateCarree()); + @savefig plotting_example_2d_irreg_map.png width=4in + ax.coastlines(); ax.gridlines(draw_labels=True); + +You can however decide to infer the cell boundaries with the +``infer_intervals`` keyword: + +.. ipython:: python + + ax = plt.subplot(projection=ccrs.PlateCarree()); + da.plot.pcolormesh('lon', 'lat', ax=ax, infer_intervals=True); + ax.scatter(lon, lat, transform=ccrs.PlateCarree()); + @savefig plotting_example_2d_irreg_map_infer.png width=4in + ax.coastlines(); ax.gridlines(draw_labels=True); + +.. note:: + The data model of xarray does not support datasets with `cell boundaries`_ + yet. If you want to use these coordinates, you'll have to make the plots + out of the xarray framework. + +.. _cell boundaries: http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#cell-boundaries diff --git a/doc/whats-new.rst b/doc/whats-new.rst index 15a0b8eb17d..ae1bbb09e9a 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -108,7 +108,7 @@ Bug fixes - ``Dataset.concat()`` now preserves variables order (:issue:`1027`). By `Fabien Maussion `_. -- Fixed a regression with pcolormesh (:issue:`781`). A new +- Fixed an issue with pcolormesh (:issue:`781`). A new ``infer_intervals`` keyword gives control on whether the cell intervals should be computed or not. By `Fabien Maussion `_. diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index 050cc9c364e..ea9a666cb88 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -318,8 +318,10 @@ def _plot2d(plotfunc): Split the colormap (cmap) into discrete color intervals. infer_intervals : bool, optional Only applies to pcolormesh. If True, the coordinate intervals are - passed to pcolormesh (the default). If False, the original coordinates - are used (this can be useful for certain map projections). + passed to pcolormesh. If False, the original coordinates are used + (this can be useful for certain map projections). The default is to + always infer intervals, unless the mesh is irregular and plotted on + a map projection. subplot_kws : dict, optional Dictionary of keyword arguments for matplotlib subplots. Only applies to FacetGrid plotting. @@ -345,7 +347,7 @@ def newplotfunc(darray, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, add_colorbar=None, add_labels=True, vmin=None, vmax=None, cmap=None, center=None, robust=False, extend=None, - levels=None, infer_intervals=True, colors=None, + levels=None, infer_intervals=None, colors=None, subplot_kws=None, cbar_ax=None, cbar_kwargs=None, **kwargs): # All 2d plots in xarray share this function signature. @@ -464,7 +466,7 @@ def plotmethod(_PlotMethods_obj, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, add_colorbar=None, add_labels=True, vmin=None, vmax=None, cmap=None, colors=None, center=None, robust=False, - extend=None, levels=None, infer_intervals=True, + extend=None, levels=None, infer_intervals=None, subplot_kws=None, cbar_ax=None, cbar_kwargs=None, **kwargs): """ The method should have the same signature as the function. @@ -550,29 +552,56 @@ def contourf(x, y, z, ax, **kwargs): return ax, primitive -def _infer_interval_breaks(coord): +def _infer_interval_breaks(coord, axis=0): """ >>> _infer_interval_breaks(np.arange(5)) array([-0.5, 0.5, 1.5, 2.5, 3.5, 4.5]) + >>> _infer_interval_breaks([[0, 1], [0, 1]], axis=1) + array([[-0.5, 0.5, 1.5], + [-0.5, 0.5, 1.5]]) """ coord = np.asarray(coord) - deltas = 0.5 * (coord[1:] - coord[:-1]) - first = coord[0] - deltas[0] - last = coord[-1] + deltas[-1] - return np.r_[[first], coord[:-1] + deltas, [last]] + if axis == 0: + deltas = 0.5 * (coord[1:, ...] - coord[:-1, ...]) + first = coord[0, ...] - deltas[0, ...] + last = coord[-1, ...] + deltas[-1, ...] + return np.r_[[first], coord[:-1, ...] + deltas, [last]] + elif axis == 1: + deltas = 0.5 * (coord[..., 1:] - coord[..., :-1]) + first = coord[..., [0]] - deltas[..., [0]] + last = coord[..., [-1]] + deltas[..., [-1]] + return np.c_[first, coord[..., :-1] + deltas, last] @_plot2d -def pcolormesh(x, y, z, ax, infer_intervals=True, **kwargs): +def pcolormesh(x, y, z, ax, infer_intervals=None, **kwargs): """ Pseudocolor plot of 2d DataArray Wraps matplotlib.pyplot.pcolormesh """ + # decide on a default for infer_intervals (GH781) + x = np.asarray(x) + if infer_intervals is None: + if hasattr(ax, 'projection'): + if len(x.shape) == 1: + infer_intervals = True + else: + infer_intervals = False + else: + infer_intervals = True + if infer_intervals: - x = _infer_interval_breaks(x) - y = _infer_interval_breaks(y) + if len(x.shape) == 1: + x = _infer_interval_breaks(x) + y = _infer_interval_breaks(y) + else: + # we have to infer the intervals on both axes + x = _infer_interval_breaks(x, axis=1) + x = _infer_interval_breaks(x, axis=0) + y = _infer_interval_breaks(y, axis=1) + y = _infer_interval_breaks(y, axis=0) primitive = ax.pcolormesh(x, y, z, **kwargs) diff --git a/xarray/test/test_plot.py b/xarray/test/test_plot.py index 2d57b2d073e..64073cbcd6b 100644 --- a/xarray/test/test_plot.py +++ b/xarray/test/test_plot.py @@ -112,6 +112,17 @@ def test__infer_interval_breaks(self): self.assertArrayEqual(pd.date_range('20000101', periods=4) - np.timedelta64(12, 'h'), _infer_interval_breaks(pd.date_range('20000101', periods=3))) + # make a bounded 2D array that we will center and re-infer + xref, yref = np.meshgrid(np.arange(6), np.arange(5)) + cx = (xref[1:, 1:] + xref[:-1, :-1]) / 2 + cy = (yref[1:, 1:] + yref[:-1, :-1]) / 2 + x = _infer_interval_breaks(cx, axis=1) + x = _infer_interval_breaks(x, axis=0) + y = _infer_interval_breaks(cy, axis=1) + y = _infer_interval_breaks(y, axis=0) + np.testing.assert_allclose(xref, x) + np.testing.assert_allclose(yref, y) + def test_datetime_dimension(self): nrow = 3 ncol = 4 From 923af9d8849534f439d87b5b9c4a365dc0c4c848 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Tue, 8 Nov 2016 20:25:22 +0100 Subject: [PATCH 6/9] revert to original cartopy test --- xarray/test/test_plot.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/xarray/test/test_plot.py b/xarray/test/test_plot.py index 64073cbcd6b..790ed46e5bb 100644 --- a/xarray/test/test_plot.py +++ b/xarray/test/test_plot.py @@ -862,12 +862,14 @@ def test_2d_coord_names(self): self.assertEqual('x2d', ax.get_xlabel()) self.assertEqual('y2d', ax.get_ylabel()) - def test_infer_interval_breaks_for_cartopy(self): - # GH 781 + def test_dont_infer_interval_breaks_for_cartopy(self): + # Regression for GH 781 ax = plt.gca() - artist = self.plotmethod(x='x2d', y='y2d', ax=ax, - infer_intervals=False) + # Simulate a Cartopy Axis + setattr(ax, 'projection', True) + artist = self.plotmethod(x='x2d', y='y2d', ax=ax) self.assertTrue(isinstance(artist, mpl.collections.QuadMesh)) + # Let cartopy handle the axis limits and artist size self.assertTrue(artist.get_array().size <= self.darray.size) From 95513dc64ce2e5c11a891ae34133723320ee8383 Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Tue, 8 Nov 2016 20:43:45 +0100 Subject: [PATCH 7/9] update docs --- doc/plotting.rst | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/doc/plotting.rst b/doc/plotting.rst index d44fbada060..9fb8f89bf19 100644 --- a/doc/plotting.rst +++ b/doc/plotting.rst @@ -523,11 +523,14 @@ the pixels are centered over their coordinates, and the axis labels and ranges correspond to the values of the coordinates. -Irregular coordinates -~~~~~~~~~~~~~~~~~~~~~ +Multidimensional coordinates +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +See also: :ref:`examples.multidim`. -You can plot irregular grids using xarray, but you'll have to tell the plot -function to use these coordinates instead: +You can plot irregular grids defined by multidimensional coordinates with +xarray, but you'll have to tell the plot function to use these coordinates +instead of the default ones: .. ipython:: python @@ -542,8 +545,9 @@ function to use these coordinates instead: da.plot.pcolormesh('lon', 'lat'); Note that in this case, xarray still follows the pixel centered convention. -This might be undesirable in some cases (e.g. :issue:`781`), and this is why -the default is to not follow this convention when plotting on a map: +This might be undesirable in some cases, for example when your data is defined +on a polar projection (:issue:`781`). This is why the default is to not follow +this convention when plotting on a map: .. ipython:: python @@ -554,7 +558,7 @@ the default is to not follow this convention when plotting on a map: @savefig plotting_example_2d_irreg_map.png width=4in ax.coastlines(); ax.gridlines(draw_labels=True); -You can however decide to infer the cell boundaries with the +You can however decide to infer the cell boundaries and use the ``infer_intervals`` keyword: .. ipython:: python @@ -568,6 +572,6 @@ You can however decide to infer the cell boundaries with the .. note:: The data model of xarray does not support datasets with `cell boundaries`_ yet. If you want to use these coordinates, you'll have to make the plots - out of the xarray framework. + outside the xarray framework. .. _cell boundaries: http://cfconventions.org/cf-conventions/v1.6.0/cf-conventions.html#cell-boundaries From d4ff6f9c5e79e0c7c456011890ad7d98fbe17a0d Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Thu, 10 Nov 2016 17:14:19 +0100 Subject: [PATCH 8/9] other version of _infer_intervals_breaks --- xarray/plot/plot.py | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-) diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index ea9a666cb88..1e4abb148a8 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -556,21 +556,17 @@ def _infer_interval_breaks(coord, axis=0): """ >>> _infer_interval_breaks(np.arange(5)) array([-0.5, 0.5, 1.5, 2.5, 3.5, 4.5]) - >>> _infer_interval_breaks([[0, 1], [0, 1]], axis=1) + >>> _infer_interval_breaks([[0, 1], [3, 4]], axis=1) array([[-0.5, 0.5, 1.5], - [-0.5, 0.5, 1.5]]) + [ 2.5, 3.5, 4.5]]) """ coord = np.asarray(coord) - if axis == 0: - deltas = 0.5 * (coord[1:, ...] - coord[:-1, ...]) - first = coord[0, ...] - deltas[0, ...] - last = coord[-1, ...] + deltas[-1, ...] - return np.r_[[first], coord[:-1, ...] + deltas, [last]] - elif axis == 1: - deltas = 0.5 * (coord[..., 1:] - coord[..., :-1]) - first = coord[..., [0]] - deltas[..., [0]] - last = coord[..., [-1]] + deltas[..., [-1]] - return np.c_[first, coord[..., :-1] + deltas, last] + deltas = 0.5 * np.diff(coord, axis=axis) + first = np.take(coord, [0], axis=axis) - np.take(deltas, [0], axis=axis) + last = np.take(coord, [-1], axis=axis) + np.take(deltas, [-1], axis=axis) + trim_last = tuple(slice(None, -1) if n == axis else slice(None) + for n in range(coord.ndim)) + return np.concatenate([first, coord[trim_last] + deltas, last], axis=axis) @_plot2d From b9ec680a8a1e7dbd0a481e9aa518cec09d8a1bee Mon Sep 17 00:00:00 2001 From: Fabien Maussion Date: Thu, 10 Nov 2016 23:37:44 +0100 Subject: [PATCH 9/9] py2 division --- xarray/test/test_plot.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/xarray/test/test_plot.py b/xarray/test/test_plot.py index 790ed46e5bb..e529f9dab83 100644 --- a/xarray/test/test_plot.py +++ b/xarray/test/test_plot.py @@ -1,3 +1,5 @@ +from __future__ import division + import inspect import numpy as np