diff --git a/lib/matplotlib/axes/_base.py b/lib/matplotlib/axes/_base.py index f86522f125ad..44dfe1b1a202 100644 --- a/lib/matplotlib/axes/_base.py +++ b/lib/matplotlib/axes/_base.py @@ -2975,7 +2975,11 @@ def _update_title_position(self, renderer): or ax.xaxis.get_label_position() == 'top'): bb = ax.xaxis.get_tightbbox(renderer) if bb is None: - bb = ax.get_window_extent(renderer) + if 'outline' in ax.spines: + # Special case for colorbars: + bb = ax.spines['outline'].get_window_extent() + else: + bb = ax.get_window_extent(renderer) top = max(top, bb.ymax) if title.get_text(): ax.yaxis.get_tightbbox(renderer) # update offsetText diff --git a/lib/matplotlib/axis.py b/lib/matplotlib/axis.py index 8fd0f41e958f..7d1dd51690be 100644 --- a/lib/matplotlib/axis.py +++ b/lib/matplotlib/axis.py @@ -2474,8 +2474,13 @@ def _update_offset_text_position(self, bboxes, bboxes2): Update the offset_text position based on the sequence of bounding boxes of all the ticklabels """ - x, y = self.offsetText.get_position() - top = self.axes.bbox.ymax + x, _ = self.offsetText.get_position() + if 'outline' in self.axes.spines: + # Special case for colorbars: + bbox = self.axes.spines['outline'].get_window_extent() + else: + bbox = self.axes.bbox + top = bbox.ymax self.offsetText.set_position( (x, top + self.OFFSETTEXTPAD * self.figure.dpi / 72) ) diff --git a/lib/matplotlib/tests/test_colorbar.py b/lib/matplotlib/tests/test_colorbar.py index 23872b7a7d35..ca540dee90d5 100644 --- a/lib/matplotlib/tests/test_colorbar.py +++ b/lib/matplotlib/tests/test_colorbar.py @@ -979,3 +979,30 @@ def test_colorbar_set_formatter_locator(): fmt = LogFormatter() cb.minorformatter = fmt assert cb.ax.yaxis.get_minor_formatter() is fmt + + +def test_offset_text_loc(): + plt.style.use('mpl20') + fig, ax = plt.subplots() + np.random.seed(seed=19680808) + pc = ax.pcolormesh(np.random.randn(10, 10)*1e6) + cb = fig.colorbar(pc, location='right', extend='max') + fig.draw_without_rendering() + # check that the offsetText is in the proper place above the + # colorbar axes. In this case the colorbar axes is the same + # height as the parent, so use the parents bbox. + assert cb.ax.yaxis.offsetText.get_position()[1] > ax.bbox.y1 + + +def test_title_text_loc(): + plt.style.use('mpl20') + fig, ax = plt.subplots() + np.random.seed(seed=19680808) + pc = ax.pcolormesh(np.random.randn(10, 10)) + cb = fig.colorbar(pc, location='right', extend='max') + cb.ax.set_title('Aardvark') + fig.draw_without_rendering() + # check that the title is in the proper place above the + # colorbar axes, including its extend triangles.... + assert (cb.ax.title.get_window_extent(fig.canvas.get_renderer()).ymax > + cb.ax.spines['outline'].get_window_extent().ymax) diff --git a/tutorials/introductory/quick_start.py b/tutorials/introductory/quick_start.py index 7c9f986606b7..3481d9dbbcc9 100644 --- a/tutorials/introductory/quick_start.py +++ b/tutorials/introductory/quick_start.py @@ -505,7 +505,7 @@ def my_plotter(ax, data1, data2, param_dict): pc = axs[1, 1].scatter(data1, data2, c=data3, cmap='RdBu_r') fig.colorbar(pc, ax=axs[1, 1], extend='both') -axs[1, 1].set_title('scatter()'); +axs[1, 1].set_title('scatter()') ############################################################################## # Colormaps