Skip to content

[Bug]: Regression on tight_layout when manually adding axes for colorbars #21749

Closed
@ryandvmartin

Description

@ryandvmartin

Bug summary

When creating manual floating axes to fill with colorbars, previous to version 3.5 a call to fig.tight_layout() on a figure with manually located axes would simply raise a warning that the figure contains axes incompatbile with tight layout.

Starting in 3.5 we get the attribute error documented below.

Code for reproduction

import matplotlib
import matplotlib.pyplot as plt
import numpy as np
matplotlib.__version__
# > '3.5.0'

def add_cax(ax):
    ax_rect = ax.get_position()
    cax = fig.add_axes(
        [ax_rect.x1 + 0.005, ax_rect.y0, 0.015, ax_rect.height]
    )
    return cax

fig, axes = plt.subplots(1, 2)
pts = axes[1].scatter([0, 1], [0, 1], c=[1, 5])
cax = add_cax(axes[1])
fig.colorbar(pts, cax=cax) 
fig.tight_layout()

Actual outcome


AttributeError Traceback (most recent call last)
/var/folders/3c/nbn0xyrs4mldy84gltty_pt00000gn/T/ipykernel_87887/4094170185.py in
3 cax = add_cax(axes[1])
4 fig.colorbar(pts, cax=cax, use_gridspec=True)
----> 5 fig.tight_layout()

~/.venv/envs/rms-2.0.0/lib/python3.9/site-packages/matplotlib/figure.py in tight_layout(self, pad, h_pad, w_pad, rect)
3181 from .tight_layout import (
3182 get_subplotspec_list, get_tight_layout_figure)
-> 3183 subplotspec_list = get_subplotspec_list(self.axes)
3184 if None in subplotspec_list:
3185 _api.warn_external("This figure includes Axes that are not "

~/.venv/envs/rms-2.0.0/lib/python3.9/site-packages/matplotlib/tight_layout.py in get_subplotspec_list(axes_list, grid_spec)
232
233 if hasattr(axes_or_locator, "get_subplotspec"):
--> 234 subplotspec = axes_or_locator.get_subplotspec()
235 subplotspec = subplotspec.get_topmost_subplotspec()
236 gs = subplotspec.get_gridspec()

~/.venv/envs/rms-2.0.0/lib/python3.9/site-packages/matplotlib/colorbar.py in get_subplotspec(self)
281 ss = getattr(self._cbar.ax, 'get_subplotspec', None)
282 if ss is None:
--> 283 ss = self._orig_locator.get_subplotspec()
284 else:
285 ss = ss()

AttributeError: 'NoneType' object has no attribute 'get_subplotspec'

Expected outcome

Expect a warning about tight layout used with incompatible axes

Additional information

Fails under Matplotlib 3.5

Works (warns) under < 3.4

Operating system

MacOS, Windows, Ubuntu

Matplotlib Version

3.5.0

Matplotlib Backend

'module://matplotlib_inline.backend_inline'

Python version

3.9.7

Jupyter version

3.2.2

Installation

conda

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions