Closed
Description
Bug summary
When I set a clipping path to quiver object with set_clip_path(), Figure.tight_layout() produces AttributeError: 'NoneType' object has no attribute 'xmin'. Without tight_layout() everything works.
Code for reproduction
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.patches import Circle
x, y = np.mgrid[-1:1:0.1, -1:1:0.1]
z = np.sin(x) + np.cos(y)
xg, yg = np.gradient(z)
f, ax = plt.subplots()
h = ax.quiver(x, y, xg, yg, label='Test')
c = Circle((0, 0), radius=1, edgecolor="black", fill=False)
ax.add_patch(c)
h.set_clip_path(c)
ax.set_aspect(1)
f.tight_layout()
Actual outcome
---------------------------------------------------------------------------
AttributeError Traceback (most recent call last)
Cell In [42], line 15
13 h.set_clip_path(c)
14 ax.set_aspect(1)
---> 15 f.tight_layout()
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/figure.py:3443, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)
3441 try:
3442 self.set_layout_engine(engine)
-> 3443 engine.execute(self)
3444 finally:
3445 self.set_layout_engine(None)
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/layout_engine.py:180, in TightLayoutEngine.execute(self, fig)
178 renderer = fig._get_renderer()
179 with getattr(renderer, "_draw_disabled", nullcontext)():
--> 180 kwargs = get_tight_layout_figure(
181 fig, fig.axes, subplotspec_list, renderer,
182 pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],
183 rect=info['rect'])
184 if kwargs:
185 fig.subplots_adjust(**kwargs)
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/_tight_layout.py:305, in get_tight_layout_figure(fig, axes_list, subplotspec_list, renderer, pad, h_pad, w_pad, rect)
300 return {}
301 span_pairs.append((
302 slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),
303 slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))
--> 305 kwargs = _auto_adjust_subplotpars(fig, renderer,
306 shape=(max_nrows, max_ncols),
307 span_pairs=span_pairs,
308 subplot_list=subplot_list,
309 ax_bbox_list=ax_bbox_list,
310 pad=pad, h_pad=h_pad, w_pad=w_pad)
312 # kwargs can be none if tight_layout fails...
313 if rect is not None and kwargs is not None:
314 # if rect is given, the whole subplots area (including
315 # labels) will fit into the rect instead of the
(...)
319 # auto_adjust_subplotpars twice, where the second run
320 # with adjusted rect parameters.
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/_tight_layout.py:82, in _auto_adjust_subplotpars(fig, renderer, shape, span_pairs, subplot_list, ax_bbox_list, pad, h_pad, w_pad, rect)
80 for ax in subplots:
81 if ax.get_visible():
---> 82 bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]
84 tight_bbox_raw = Bbox.union(bb)
85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/artist.py:1378, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)
1372 """
1373 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a
1374 *for_layout_only* kwarg; this helper tries to uses the kwarg but skips it
1375 when encountering third-party subclasses that do not support it.
1376 """
1377 try:
-> 1378 return obj.get_tightbbox(*args, **{**kwargs, "for_layout_only": True})
1379 except TypeError:
1380 return obj.get_tightbbox(*args, **kwargs)
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/axes/_base.py:4450, in _AxesBase.get_tightbbox(self, renderer, call_axes_locator, bbox_extra_artists, for_layout_only)
4447 bbox_artists = self.get_default_bbox_extra_artists()
4449 for a in bbox_artists:
-> 4450 bbox = a.get_tightbbox(renderer)
4451 if (bbox is not None
4452 and 0 < bbox.width < np.inf
4453 and 0 < bbox.height < np.inf):
4454 bb.append(bbox)
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/artist.py:345, in Artist.get_tightbbox(self, renderer)
343 if clip_path is not None:
344 clip_path = clip_path.get_fully_transformed_path()
--> 345 bbox = Bbox.intersection(bbox, clip_path.get_extents())
346 return bbox
File ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/transforms.py:666, in BboxBase.intersection(bbox1, bbox2)
660 @staticmethod
661 def intersection(bbox1, bbox2):
662 """
663 Return the intersection of *bbox1* and *bbox2* if they intersect, or
664 None if they don't.
665 """
--> 666 x0 = np.maximum(bbox1.xmin, bbox2.xmin)
667 x1 = np.minimum(bbox1.xmax, bbox2.xmax)
668 y0 = np.maximum(bbox1.ymin, bbox2.ymin)
AttributeError: 'NoneType' object has no attribute 'xmin'
Expected outcome
No error
Additional information
No response
Operating system
Ubuntu
Matplotlib Version
3.6.0
Matplotlib Backend
module://matplotlib_inline.backend_inline
Python version
3.10.6
Jupyter version
3.4.8
Installation
conda
Metadata
Metadata
Assignees
Labels
No labels