diff --git a/lib/matplotlib/colorbar.py b/lib/matplotlib/colorbar.py index 8dc6b7c5e624..8504cfbd5c33 100644 --- a/lib/matplotlib/colorbar.py +++ b/lib/matplotlib/colorbar.py @@ -240,7 +240,8 @@ def tick_values(self, vmin, vmax): vmin = max(vmin, self._colorbar.norm.vmin) vmax = min(vmax, self._colorbar.norm.vmax) ticks = super().tick_values(vmin, vmax) - return ticks[(ticks >= vmin) & (ticks <= vmax)] + rtol = (vmax - vmin) * 1e-10 + return ticks[(ticks >= vmin - rtol) & (ticks <= vmax + rtol)] class _ColorbarAutoMinorLocator(ticker.AutoMinorLocator): @@ -296,7 +297,10 @@ def tick_values(self, vmin, vmax): vmin = self._colorbar.norm.vmin vmax = self._colorbar.norm.vmax ticks = super().tick_values(vmin, vmax) - return ticks[(ticks >= vmin) & (ticks <= vmax)] + rtol = (np.log10(vmax) - np.log10(vmin)) * 1e-10 + ticks = ticks[(np.log10(ticks) >= np.log10(vmin) - rtol) & + (np.log10(ticks) <= np.log10(vmax) + rtol)] + return ticks class ColorbarBase(cm.ScalarMappable): @@ -405,7 +409,6 @@ def __init__(self, ax, cmap=None, else: self.formatter = format # Assume it is a Formatter # The rest is in a method so we can recalculate when clim changes. - self.config_axis() self.draw_all() def _extend_lower(self): @@ -439,6 +442,7 @@ def draw_all(self): # units: X, Y = self._mesh() C = self._values[:, np.newaxis] + self.config_axis() self._config_axes(X, Y) if self.filled: self._add_solids(X, Y, C) @@ -593,6 +597,7 @@ def _config_axes(self, X, Y): ax.set_frame_on(False) ax.set_navigate(False) xy = self._outline(X, Y) + ax.ignore_existing_data_limits = True ax.update_datalim(xy) ax.set_xlim(*ax.dataLim.intervalx) ax.set_ylim(*ax.dataLim.intervaly) @@ -1150,7 +1155,6 @@ def update_bruteforce(self, mappable): self.set_alpha(mappable.get_alpha()) self.cmap = mappable.cmap self.norm = mappable.norm - self.config_axis() self.draw_all() if isinstance(self.mappable, contour.ContourSet): CS = self.mappable diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index fd2a7d52c7b6..6137da4afdba 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -7,6 +7,7 @@ from matplotlib.colors import BoundaryNorm, LogNorm, PowerNorm from matplotlib.cm import get_cmap from matplotlib.colorbar import ColorbarBase +from matplotlib.ticker import LogLocator, LogFormatter def _get_cmap_norms(): @@ -411,3 +412,27 @@ def test_colorbar_log_minortick_labels(): r'$\mathdefault{4\times10^{4}}$'] for l, exp in zip(lb, expected): assert l.get_text() == exp + + +def test_colorbar_renorm(): + x, y = np.ogrid[-4:4:31j, -4:4:31j] + z = 120000*np.exp(-x**2 - y**2) + + fig, ax = plt.subplots() + im = ax.imshow(z) + cbar = fig.colorbar(im) + + norm = LogNorm(z.min(), z.max()) + im.set_norm(norm) + cbar.set_norm(norm) + cbar.locator = LogLocator() + cbar.formatter = LogFormatter() + cbar.update_normal(im) + assert np.isclose(cbar.vmin, z.min()) + + norm = LogNorm(z.min() * 1000, z.max() * 1000) + im.set_norm(norm) + cbar.set_norm(norm) + cbar.update_normal(im) + assert np.isclose(cbar.vmin, z.min() * 1000) + assert np.isclose(cbar.vmax, z.max() * 1000)