diff --git a/doc/whats-new.rst b/doc/whats-new.rst index bb10d3e5796..ca462e8e1fd 100644 --- a/doc/whats-new.rst +++ b/doc/whats-new.rst @@ -29,6 +29,7 @@ Breaking changes - Indexing on multi-index now drop levels, which is consitent with pandas. It also changes the name of the dimension / coordinate when the multi-index is reduced to a single index. +- Contour plots no longer add a colorbar per default (:issue:`866`). Enhancements ~~~~~~~~~~~~ @@ -100,6 +101,9 @@ Bug fixes - Fixed incorrect test for dask version :issue:`891`. By `Stephan Hoyer `_. +- :py:func:`~xarray.plot.contour` now plots the correct number of contours + (:issue:`866`). By `Fabien Maussion `_. + .. _whats-new.0.7.2: v0.7.2 (13 March 2016) diff --git a/xarray/plot/plot.py b/xarray/plot/plot.py index cad5ee4cac3..11a32e9f85e 100644 --- a/xarray/plot/plot.py +++ b/xarray/plot/plot.py @@ -339,13 +339,17 @@ def _plot2d(plotfunc): @functools.wraps(plotfunc) def newplotfunc(darray, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, - add_colorbar=True, add_labels=True, vmin=None, vmax=None, + 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): # All 2d plots in xarray share this function signature. # Method signature below should be consistent. + # Decide on a default for the colorbar before facetgrids + if add_colorbar is None: + add_colorbar = plotfunc.__name__ != 'contour' + # Handle facetgrids first if row or col: allargs = locals().copy() @@ -450,7 +454,7 @@ def newplotfunc(darray, x=None, y=None, ax=None, row=None, col=None, @functools.wraps(newplotfunc) def plotmethod(_PlotMethods_obj, x=None, y=None, ax=None, row=None, col=None, col_wrap=None, xincrease=True, yincrease=True, - add_colorbar=True, add_labels=True, vmin=None, vmax=None, + 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): diff --git a/xarray/plot/utils.py b/xarray/plot/utils.py index 5e4b11a4ab4..e9fb1de98d6 100644 --- a/xarray/plot/utils.py +++ b/xarray/plot/utils.py @@ -41,7 +41,7 @@ def _build_discrete_cmap(cmap, levels, extend, filled): if not filled: # non-filled contour plots - extend = 'neither' + extend = 'max' if extend == 'both': ext_n = 2 diff --git a/xarray/test/test_plot.py b/xarray/test/test_plot.py index 8b0a699b9ed..4e812d2b602 100644 --- a/xarray/test/test_plot.py +++ b/xarray/test/test_plot.py @@ -414,7 +414,7 @@ def test_build_discrete_cmap(self): if filled: self.assertEqual(ncmap.colorbar_extend, extend) else: - self.assertEqual(ncmap.colorbar_extend, 'neither') + self.assertEqual(ncmap.colorbar_extend, 'max') def test_discrete_colormap_list_of_levels(self): for extend, levels in [('max', [-1, 2, 4, 8, 10]), @@ -429,7 +429,7 @@ def test_discrete_colormap_list_of_levels(self): if kind != 'contour': self.assertEqual(extend, primitive.cmap.colorbar_extend) else: - self.assertEqual('neither', primitive.cmap.colorbar_extend) + self.assertEqual('max', primitive.cmap.colorbar_extend) self.assertEqual(len(levels) - 1, len(primitive.cmap.colors)) def test_discrete_colormap_int_levels(self): @@ -454,7 +454,7 @@ def test_discrete_colormap_int_levels(self): if kind != 'contour': self.assertEqual(extend, primitive.cmap.colorbar_extend) else: - self.assertEqual('neither', primitive.cmap.colorbar_extend) + self.assertEqual('max', primitive.cmap.colorbar_extend) self.assertGreaterEqual(levels, len(primitive.cmap.colors)) def test_discrete_colormap_list_levels_and_vmin_or_vmax(self): @@ -620,7 +620,7 @@ def test_default_title(self): def test_colorbar_default_label(self): self.darray.name = 'testvar' - self.plotmethod() + self.plotmethod(add_colorbar=True) self.assertIn(self.darray.name, text_in_fig()) def test_no_labels(self): @@ -633,18 +633,19 @@ def test_no_labels(self): def test_colorbar_kwargs(self): # replace label self.darray.name = 'testvar' - self.plotmethod(cbar_kwargs={'label':'MyLabel'}) + self.plotmethod(add_colorbar=True, cbar_kwargs={'label':'MyLabel'}) alltxt = text_in_fig() self.assertIn('MyLabel', alltxt) self.assertNotIn('testvar', alltxt) # you can use mapping types as well - self.plotmethod(cbar_kwargs=(('label', 'MyLabel'),)) + self.plotmethod(add_colorbar=True, cbar_kwargs=(('label', 'MyLabel'),)) alltxt = text_in_fig() self.assertIn('MyLabel', alltxt) self.assertNotIn('testvar', alltxt) # change cbar ax fig, (ax, cax) = plt.subplots(1, 2) - self.plotmethod(ax=ax, cbar_ax=cax, cbar_kwargs={'label':'MyBar'}) + self.plotmethod(ax=ax, cbar_ax=cax, add_colorbar=True, + cbar_kwargs={'label':'MyBar'}) self.assertTrue(ax.has_data()) self.assertTrue(cax.has_data()) alltxt = text_in_fig() @@ -652,7 +653,8 @@ def test_colorbar_kwargs(self): self.assertNotIn('testvar', alltxt) # note that there are two ways to achieve this fig, (ax, cax) = plt.subplots(1, 2) - self.plotmethod(ax=ax, cbar_kwargs={'label':'MyBar', 'cax':cax}) + self.plotmethod(ax=ax, add_colorbar=True, + cbar_kwargs={'label':'MyBar', 'cax':cax}) self.assertTrue(ax.has_data()) self.assertTrue(cax.has_data()) alltxt = text_in_fig() @@ -795,6 +797,19 @@ def _color_as_tuple(c): _color_as_tuple(artist.cmap.colors[1]), (0.0, 0.0, 1.0)) + artist = self.darray.plot.contour(levels=[-0.5, 0., 0.5, 1.], + colors=['k', 'r', 'w', 'b']) + self.assertEqual( + _color_as_tuple(artist.cmap.colors[1]), + (1.0, 0.0, 0.0)) + self.assertEqual( + _color_as_tuple(artist.cmap.colors[2]), + (1.0, 1.0, 1.0)) + # the last color is now under "over" + self.assertEqual( + _color_as_tuple(artist.cmap._rgba_over), + (0.0, 0.0, 1.0)) + def test_cmap_and_color_both(self): with self.assertRaises(ValueError): self.plotmethod(colors='k', cmap='RdBu') @@ -810,6 +825,12 @@ def test_2d_coord_names(self): self.assertEqual('x2d', ax.get_xlabel()) self.assertEqual('y2d', ax.get_ylabel()) + def test_single_level(self): + # this used to raise an error, but not anymore since + # add_colorbar defaults to false + self.plotmethod(levels=[0.1]) + self.plotmethod(levels=1) + class TestPcolormesh(Common2dMixin, PlotTestCase):