Title: [Bug]: fig.tight_layout when quiver collection is clipped produces AttributeError · Issue #24104 · matplotlib/matplotlib · GitHub
Open Graph Title: [Bug]: fig.tight_layout when quiver collection is clipped produces AttributeError · Issue #24104 · matplotlib/matplotlib
X Title: [Bug]: fig.tight_layout when quiver collection is clipped produces AttributeError · Issue #24104 · matplotlib/matplotlib
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...
Open Graph 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() everyt...
X 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...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/24104
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[Bug]: fig.tight_layout when quiver collection is clipped produces AttributeError","articleBody":"### Bug summary\r\n\r\nWhen 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.\r\n\r\n### Code for reproduction\r\n\r\n```python\r\nimport numpy as np\r\nimport matplotlib.pyplot as plt\r\nfrom matplotlib.patches import Circle\r\n\r\nx, y = np.mgrid[-1:1:0.1, -1:1:0.1]\r\nz = np.sin(x) + np.cos(y)\r\nxg, yg = np.gradient(z)\r\n\r\nf, ax = plt.subplots()\r\nh = ax.quiver(x, y, xg, yg, label='Test')\r\nc = Circle((0, 0), radius=1, edgecolor=\"black\", fill=False)\r\nax.add_patch(c)\r\nh.set_clip_path(c)\r\nax.set_aspect(1)\r\nf.tight_layout()\r\n```\r\n\r\n\r\n### Actual outcome\r\n```\r\n---------------------------------------------------------------------------\r\nAttributeError Traceback (most recent call last)\r\nCell In [42], line 15\r\n 13 h.set_clip_path(c)\r\n 14 ax.set_aspect(1)\r\n---\u003e 15 f.tight_layout()\r\n\r\nFile ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/figure.py:3443, in Figure.tight_layout(self, pad, h_pad, w_pad, rect)\r\n 3441 try:\r\n 3442 self.set_layout_engine(engine)\r\n-\u003e 3443 engine.execute(self)\r\n 3444 finally:\r\n 3445 self.set_layout_engine(None)\r\n\r\nFile ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/layout_engine.py:180, in TightLayoutEngine.execute(self, fig)\r\n 178 renderer = fig._get_renderer()\r\n 179 with getattr(renderer, \"_draw_disabled\", nullcontext)():\r\n--\u003e 180 kwargs = get_tight_layout_figure(\r\n 181 fig, fig.axes, subplotspec_list, renderer,\r\n 182 pad=info['pad'], h_pad=info['h_pad'], w_pad=info['w_pad'],\r\n 183 rect=info['rect'])\r\n 184 if kwargs:\r\n 185 fig.subplots_adjust(**kwargs)\r\n\r\nFile ~/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)\r\n 300 return {}\r\n 301 span_pairs.append((\r\n 302 slice(ss.rowspan.start * div_row, ss.rowspan.stop * div_row),\r\n 303 slice(ss.colspan.start * div_col, ss.colspan.stop * div_col)))\r\n--\u003e 305 kwargs = _auto_adjust_subplotpars(fig, renderer,\r\n 306 shape=(max_nrows, max_ncols),\r\n 307 span_pairs=span_pairs,\r\n 308 subplot_list=subplot_list,\r\n 309 ax_bbox_list=ax_bbox_list,\r\n 310 pad=pad, h_pad=h_pad, w_pad=w_pad)\r\n 312 # kwargs can be none if tight_layout fails...\r\n 313 if rect is not None and kwargs is not None:\r\n 314 # if rect is given, the whole subplots area (including\r\n 315 # labels) will fit into the rect instead of the\r\n (...)\r\n 319 # auto_adjust_subplotpars twice, where the second run\r\n 320 # with adjusted rect parameters.\r\n\r\nFile ~/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)\r\n 80 for ax in subplots:\r\n 81 if ax.get_visible():\r\n---\u003e 82 bb += [martist._get_tightbbox_for_layout_only(ax, renderer)]\r\n 84 tight_bbox_raw = Bbox.union(bb)\r\n 85 tight_bbox = fig.transFigure.inverted().transform_bbox(tight_bbox_raw)\r\n\r\nFile ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/artist.py:1378, in _get_tightbbox_for_layout_only(obj, *args, **kwargs)\r\n 1372 \"\"\"\r\n 1373 Matplotlib's `.Axes.get_tightbbox` and `.Axis.get_tightbbox` support a\r\n 1374 *for_layout_only* kwarg; this helper tries to uses the kwarg but skips it\r\n 1375 when encountering third-party subclasses that do not support it.\r\n 1376 \"\"\"\r\n 1377 try:\r\n-\u003e 1378 return obj.get_tightbbox(*args, **{**kwargs, \"for_layout_only\": True})\r\n 1379 except TypeError:\r\n 1380 return obj.get_tightbbox(*args, **kwargs)\r\n\r\nFile ~/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)\r\n 4447 bbox_artists = self.get_default_bbox_extra_artists()\r\n 4449 for a in bbox_artists:\r\n-\u003e 4450 bbox = a.get_tightbbox(renderer)\r\n 4451 if (bbox is not None\r\n 4452 and 0 \u003c bbox.width \u003c np.inf\r\n 4453 and 0 \u003c bbox.height \u003c np.inf):\r\n 4454 bb.append(bbox)\r\n\r\nFile ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/artist.py:345, in Artist.get_tightbbox(self, renderer)\r\n 343 if clip_path is not None:\r\n 344 clip_path = clip_path.get_fully_transformed_path()\r\n--\u003e 345 bbox = Bbox.intersection(bbox, clip_path.get_extents())\r\n 346 return bbox\r\n\r\nFile ~/miniforge3/envs/apsg/lib/python3.10/site-packages/matplotlib/transforms.py:666, in BboxBase.intersection(bbox1, bbox2)\r\n 660 @staticmethod\r\n 661 def intersection(bbox1, bbox2):\r\n 662 \"\"\"\r\n 663 Return the intersection of *bbox1* and *bbox2* if they intersect, or\r\n 664 None if they don't.\r\n 665 \"\"\"\r\n--\u003e 666 x0 = np.maximum(bbox1.xmin, bbox2.xmin)\r\n 667 x1 = np.minimum(bbox1.xmax, bbox2.xmax)\r\n 668 y0 = np.maximum(bbox1.ymin, bbox2.ymin)\r\n\r\nAttributeError: 'NoneType' object has no attribute 'xmin'\r\n```\r\n\r\n### Expected outcome\r\n\r\nNo error\r\n\r\n### Additional information\r\n\r\n_No response_\r\n\r\n### Operating system\r\n\r\nUbuntu\r\n\r\n### Matplotlib Version\r\n\r\n3.6.0\r\n\r\n### Matplotlib Backend\r\n\r\nmodule://matplotlib_inline.backend_inline\r\n\r\n### Python version\r\n\r\n3.10.6\r\n\r\n### Jupyter version\r\n\r\n3.4.8\r\n\r\n### Installation\r\n\r\nconda","author":{"url":"https://github.com/ondrolexa","@type":"Person","name":"ondrolexa"},"datePublished":"2022-10-06T11:31:10.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":7},"url":"https://github.com/24104/matplotlib/issues/24104"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:f13a9a98-3983-5058-10dd-6d085daac064 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | B922:19F60D:250885C:313BEA4:6A520D48 |
| html-safe-nonce | 12ebc644d774d14dcf88ec0f8ae7928a80ba62b50b309442bdf3d8069850d4a1 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJCOTIyOjE5RjYwRDoyNTA4ODVDOjMxM0JFQTQ6NkE1MjBENDgiLCJ2aXNpdG9yX2lkIjoiMjUxNDE4Njc0MjA0MDQ5NzQ4MCIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 888b33e834acac5561a98e355baaf0cc8d01d3682d1acdc05dd01ddcb047e344 |
| hovercard-subject-tag | issue:1399419807 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/matplotlib/matplotlib/24104/issue_layout |
| twitter:image | https://opengraph.githubassets.com/07111881fbd7a0c54678a4efcd13a46880d522d2853c4283eb395853c20f79b6/matplotlib/matplotlib/issues/24104 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/07111881fbd7a0c54678a4efcd13a46880d522d2853c4283eb395853c20f79b6/matplotlib/matplotlib/issues/24104 |
| og:image:alt | 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() everyt... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | ondrolexa |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| go-import | github.com/matplotlib/matplotlib git https://github.com/matplotlib/matplotlib.git |
| octolytics-dimension-user_id | 215947 |
| octolytics-dimension-user_login | matplotlib |
| octolytics-dimension-repository_id | 1385122 |
| octolytics-dimension-repository_nwo | matplotlib/matplotlib |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1385122 |
| octolytics-dimension-repository_network_root_nwo | matplotlib/matplotlib |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 7aed05249554b889eb33d002851a973eebcc7e91 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width