-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[Bug]: Axes.label_outer() does not work when there is a colorbar #27305
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
Can you try w layout='constrained'. I think with normal colorbars the parent axes gets shoved down a level in the subplot spec and hence becomes "outer" to the axes/colorbar pair. This doesn't happen for layout='constrained' or in the colorbar you can also do use_gridspec=False and I think that will fix the issue |
I checked, and my diagnosis above is correct. Given that there are at least three work arounds for this, I don't know what the appetite is to check if the axes is embedded in a subplotsepc with a colorbar, and that the parent subplotspec is "inner". I'd recommend using layout='constrained' |
The following patch implements the necessary checking of gridspecs for non-constrainedlayout-positioned colorbars, AFAICT: diff --git i/lib/matplotlib/axes/_base.py w/lib/matplotlib/axes/_base.py
index b113b0f211..ac991167e1 100644
--- i/lib/matplotlib/axes/_base.py
+++ w/lib/matplotlib/axes/_base.py
@@ -4560,13 +4560,41 @@ class _AxesBase(martist.Artist):
self._label_outer_yaxis(skip_non_rectangular_axes=False,
remove_inner_ticks=remove_inner_ticks)
+ def _get_subplotspec_with_optional_colorbar(self):
+ """
+ Return the subplotspec for this Axes, except that if this Axes has been
+ moved to a subgridspec to make room for a colorbar, then return the
+ subplotspec that encloses both this Axes and the colorbar Axes.
+ """
+ ss = self.get_subplotspec()
+ if not ss:
+ return
+ gs = ss.get_gridspec()
+ if (isinstance(gs, mpl.gridspec.GridSpecFromSubplotSpec)
+ and gs.nrows * gs.ncols == 2):
+ for ax in self.figure.axes:
+ if (ax is not self
+ and hasattr(ax, "_colorbar_info")
+ and ax.get_subplotspec()
+ and isinstance(ax.get_subplotspec().get_gridspec(),
+ mpl.gridspec.GridSpecFromSubplotSpec)
+ and isinstance(ax.get_subplotspec().get_gridspec()
+ ._subplot_spec.get_gridspec(),
+ mpl.gridspec.GridSpecFromSubplotSpec)
+ and (ax.get_subplotspec().get_gridspec()
+ ._subplot_spec.get_gridspec()._subplot_spec
+ is gs._subplot_spec)):
+ ss = gs._subplot_spec
+ break
+ return ss
+
def _label_outer_xaxis(self, *, skip_non_rectangular_axes,
remove_inner_ticks=False):
# see documentation in label_outer.
if skip_non_rectangular_axes and not isinstance(self.patch,
mpl.patches.Rectangle):
return
- ss = self.get_subplotspec()
+ ss = self._get_subplotspec_with_optional_colorbar()
if not ss:
return
label_position = self.xaxis.get_label_position()
@@ -4593,7 +4621,7 @@ class _AxesBase(martist.Artist):
if skip_non_rectangular_axes and not isinstance(self.patch,
mpl.patches.Rectangle):
return
- ss = self.get_subplotspec()
+ ss = self._get_subplotspec_with_optional_colorbar()
if not ss:
return
label_position = self.yaxis.get_label_position() |
Ha, cross-post. I'm still not convinced the above is worth the bother, but wouldn't block if someone wanted to add it. |
Will #27306 simplify the patch? |
Yes, this patch is what motivated #27306 in fact (you'll only need to dig one gridspec in rather than two). |
The simplified patch now that #27306 has been merged: diff --git i/lib/matplotlib/axes/_base.py w/lib/matplotlib/axes/_base.py
index b113b0f211..07f767c253 100644
--- i/lib/matplotlib/axes/_base.py
+++ w/lib/matplotlib/axes/_base.py
@@ -4560,13 +4560,37 @@ class _AxesBase(martist.Artist):
self._label_outer_yaxis(skip_non_rectangular_axes=False,
remove_inner_ticks=remove_inner_ticks)
+ def _get_subplotspec_with_optional_colorbar(self):
+ """
+ Return the subplotspec for this Axes, except that if this Axes has been
+ moved to a subgridspec to make room for a colorbar, then return the
+ subplotspec that encloses both this Axes and the colorbar Axes.
+ """
+ ss = self.get_subplotspec()
+ if not ss:
+ return
+ gs = ss.get_gridspec()
+ if (isinstance(gs, mpl.gridspec.GridSpecFromSubplotSpec)
+ and gs.nrows * gs.ncols == 6):
+ for ax in self.figure.axes:
+ if (ax is not self
+ and hasattr(ax, "_colorbar_info")
+ and ax.get_subplotspec()
+ and isinstance(ax.get_subplotspec().get_gridspec(),
+ mpl.gridspec.GridSpecFromSubplotSpec)
+ and (ax.get_subplotspec().get_gridspec()._subplot_spec
+ is gs._subplot_spec)):
+ ss = gs._subplot_spec
+ break
+ return ss
+
def _label_outer_xaxis(self, *, skip_non_rectangular_axes,
remove_inner_ticks=False):
# see documentation in label_outer.
if skip_non_rectangular_axes and not isinstance(self.patch,
mpl.patches.Rectangle):
return
- ss = self.get_subplotspec()
+ ss = self._get_subplotspec_with_optional_colorbar()
if not ss:
return
label_position = self.xaxis.get_label_position()
@@ -4593,7 +4617,7 @@ class _AxesBase(martist.Artist):
if skip_non_rectangular_axes and not isinstance(self.patch,
mpl.patches.Rectangle):
return
- ss = self.get_subplotspec()
+ ss = self._get_subplotspec_with_optional_colorbar()
if not ss:
return
label_position = self.yaxis.get_label_position() |
Bug summary
Axes.label_outer()
fails to hide axis and tick labels for plots that have a colorbar.Code for reproduction
Actual outcome
The output of the code above gives:
Expected outcome
I would have expected the plot to look like:
This expected plot was created by creating the colorbar after the
ax.label_outer()
calls. However, I would not have expected this to have affected whether the labels/ticks are removed.Additional information
No response
Operating system
Ubuntu 20.04.5 LTS
Matplotlib Version
3.8.0
Matplotlib Backend
module://matplotlib_inline.backend_inline
Python version
Python 3.11.6
Jupyter version
7.0.6
Installation
conda
The text was updated successfully, but these errors were encountered: