diff --git a/xarray/plot/dataarray_plot.py b/xarray/plot/dataarray_plot.py index 537fbd5bafb..d3459791a89 100644 --- a/xarray/plot/dataarray_plot.py +++ b/xarray/plot/dataarray_plot.py @@ -1581,11 +1581,14 @@ def newplotfunc( ) if "contour" in plotfunc.__name__: + from matplotlib import ticker + # extend is a keyword argument only for contour and contourf, but # passing it to the colorbar is sufficient for imshow and # pcolormesh kwargs["extend"] = cmap_params["extend"] - kwargs["levels"] = cmap_params["levels"] + if not (isinstance(kwargs.get("locator"), ticker.LogLocator)): + kwargs["levels"] = cmap_params["levels"] # if colors == a single color, matplotlib draws dashed negative # contours. we lose this feature if we pass cmap and not colors if isinstance(colors, str): diff --git a/xarray/tests/test_plot.py b/xarray/tests/test_plot.py index 790ee416e82..e4d0aa2d2a2 100644 --- a/xarray/tests/test_plot.py +++ b/xarray/tests/test_plot.py @@ -1771,6 +1771,16 @@ def test_levels(self) -> None: artist = self.plotmethod(levels=3) assert artist.extend == "neither" + def test_cbar_logscale(self) -> None: + _darray = self.darray.copy() + _darray.values = np.abs(_darray.values) + _darray.plot.contourf( + norm=mpl.colors.LogNorm(vmin=0.1, vmax=10), locator=mpl.ticker.LogLocator() + ) + ax = plt.gca() + cbar = ax.figure.colorbar(ax.collections[0], ax=ax) + np.testing.assert_array_equal(cbar.get_ticks(), np.logspace(-3, 1, num=5)) + @pytest.mark.slow class TestContour(Common2dMixin, PlotTestCase):