Title: [Bug]: Cannot draw arrow from polar plot origin after setting rticks · Issue #29516 · matplotlib/matplotlib · GitHub
Open Graph Title: [Bug]: Cannot draw arrow from polar plot origin after setting rticks · Issue #29516 · matplotlib/matplotlib
X Title: [Bug]: Cannot draw arrow from polar plot origin after setting rticks · Issue #29516 · matplotlib/matplotlib
Description: Bug summary I am trying to create a polar plot of some data, with an annotation arrow pointing towards some other point in the plot. However, I get a StopIteration, presumably because of setting the rticks, which unexpectedly excludes th...
Open Graph Description: Bug summary I am trying to create a polar plot of some data, with an annotation arrow pointing towards some other point in the plot. However, I get a StopIteration, presumably because of setting th...
X Description: Bug summary I am trying to create a polar plot of some data, with an annotation arrow pointing towards some other point in the plot. However, I get a StopIteration, presumably because of setting th...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/29516
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[Bug]: Cannot draw arrow from polar plot origin after setting rticks","articleBody":"### Bug summary\n\nI am trying to create a polar plot of some data, with an annotation arrow pointing towards some other point in the plot. However, I get a StopIteration, presumably because of setting the rticks, which unexpectedly excludes the origin from the radius limits.\n\n### Code for reproduction\n\n```Python\nimport numpy as np\nimport matplotlib.pyplot as plt\n\n# Radius, random numbers in [0, 1)\nrng = np.random.default_rng(seed=42)\nr = rng.random((24,))\n\n# 0 to 2pi\ntheta = np.linspace(0, 2, 24, endpoint=False) * np.pi\n\nfig, ax = plt.subplots(subplot_kw={'projection': 'polar'})\n\n# Data to plot\nax.plot(theta, r)\nax.scatter(theta, r, c=r, cmap='viridis')\nax.set_rticks([1, 2, 3]) # Less radial ticks\nax.grid(True)\n\n# Where the annotation arrow should point\nan_r = 0.670\nan_theta = 0.820\n\n# Visualise arrow end-point\nax.scatter(an_theta, an_r)\n\n# Create arrow\nax.annotate('',\n xy=(an_theta, an_r), # theta, radius\n xytext=(0, 0), \n arrowprops=dict(facecolor='black', shrink=0),\n horizontalalignment='right'\n )\n\nplt.show()\n```\n\n### Actual outcome\n\n---------------------------------------------------------------------------\nStopIteration Traceback (most recent call last)\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/IPython/core/formatters.py:340](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/IPython/core/formatters.py#line=339), in BaseFormatter.__call__(self, obj)\n 338 pass\n 339 else:\n--\u003e 340 return printer(obj)\n 341 # Finally look for special method names\n 342 method = get_real_method(obj, self.print_method)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/IPython/core/pylabtools.py:152](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/IPython/core/pylabtools.py#line=151), in print_figure(fig, fmt, bbox_inches, base64, **kwargs)\n 149 from matplotlib.backend_bases import FigureCanvasBase\n 150 FigureCanvasBase(fig)\n--\u003e 152 fig.canvas.print_figure(bytes_io, **kw)\n 153 data = bytes_io.getvalue()\n 154 if fmt == 'svg':\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/backend_bases.py:2342](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/backend_bases.py#line=2341), in FigureCanvasBase.print_figure(self, filename, dpi, facecolor, edgecolor, orientation, format, bbox_inches, pad_inches, bbox_extra_artists, backend, **kwargs)\n 2336 renderer = _get_renderer(\n 2337 self.figure,\n 2338 functools.partial(\n 2339 print_method, orientation=orientation)\n 2340 )\n 2341 with getattr(renderer, \"_draw_disabled\", nullcontext)():\n-\u003e 2342 self.figure.draw(renderer)\n 2344 if bbox_inches:\n 2345 if bbox_inches == \"tight\":\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py:95](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py#line=94), in _finalize_rasterization.\u003clocals\u003e.draw_wrapper(artist, renderer, *args, **kwargs)\n 93 @wraps(draw)\n 94 def draw_wrapper(artist, renderer, *args, **kwargs):\n---\u003e 95 result = draw(artist, renderer, *args, **kwargs)\n 96 if renderer._rasterizing:\n 97 renderer.stop_rasterizing()\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py:72](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py#line=71), in allow_rasterization.\u003clocals\u003e.draw_wrapper(artist, renderer)\n 69 if artist.get_agg_filter() is not None:\n 70 renderer.start_filter()\n---\u003e 72 return draw(artist, renderer)\n 73 finally:\n 74 if artist.get_agg_filter() is not None:\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/figure.py:3140](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/figure.py#line=3139), in Figure.draw(self, renderer)\n 3137 # ValueError can occur when resizing a window.\n 3139 self.patch.draw(renderer)\n-\u003e 3140 mimage._draw_list_compositing_images(\n 3141 renderer, self, artists, self.suppressComposite)\n 3143 for sfig in self.subfigs:\n 3144 sfig.draw(renderer)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/image.py:131](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/image.py#line=130), in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)\n 129 if not_composite or not has_images:\n 130 for a in artists:\n--\u003e 131 a.draw(renderer)\n 132 else:\n 133 # Composite any adjacent images together\n 134 image_group = []\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py:39](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py#line=38), in _prevent_rasterization.\u003clocals\u003e.draw_wrapper(artist, renderer, *args, **kwargs)\n 36 renderer.stop_rasterizing()\n 37 renderer._rasterizing = False\n---\u003e 39 return draw(artist, renderer, *args, **kwargs)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/projections/polar.py:1037](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/projections/polar.py#line=1036), in PolarAxes.draw(self, renderer)\n 1034 self.yaxis.reset_ticks()\n 1035 self.yaxis.set_clip_path(self.patch)\n-\u003e 1037 super().draw(renderer)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py:72](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py#line=71), in allow_rasterization.\u003clocals\u003e.draw_wrapper(artist, renderer)\n 69 if artist.get_agg_filter() is not None:\n 70 renderer.start_filter()\n---\u003e 72 return draw(artist, renderer)\n 73 finally:\n 74 if artist.get_agg_filter() is not None:\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/axes/_base.py:3064](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/axes/_base.py#line=3063), in _AxesBase.draw(self, renderer)\n 3061 if artists_rasterized:\n 3062 _draw_rasterized(self.figure, artists_rasterized, renderer)\n-\u003e 3064 mimage._draw_list_compositing_images(\n 3065 renderer, self, artists, self.figure.suppressComposite)\n 3067 renderer.close_group('axes')\n 3068 self.stale = False\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/image.py:131](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/image.py#line=130), in _draw_list_compositing_images(renderer, parent, artists, suppress_composite)\n 129 if not_composite or not has_images:\n 130 for a in artists:\n--\u003e 131 a.draw(renderer)\n 132 else:\n 133 # Composite any adjacent images together\n 134 image_group = []\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py:72](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py#line=71), in allow_rasterization.\u003clocals\u003e.draw_wrapper(artist, renderer)\n 69 if artist.get_agg_filter() is not None:\n 70 renderer.start_filter()\n---\u003e 72 return draw(artist, renderer)\n 73 finally:\n 74 if artist.get_agg_filter() is not None:\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/text.py:2032](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/text.py#line=2031), in Annotation.draw(self, renderer)\n 2030 if self.arrow_patch.figure is None and self.figure is not None:\n 2031 self.arrow_patch.figure = self.figure\n-\u003e 2032 self.arrow_patch.draw(renderer)\n 2033 # Draw text, including FancyBboxPatch, after FancyArrowPatch.\n 2034 # Otherwise, a wedge arrowstyle can land partly on top of the Bbox.\n 2035 Text.draw(self, renderer)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py:39](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/artist.py#line=38), in _prevent_rasterization.\u003clocals\u003e.draw_wrapper(artist, renderer, *args, **kwargs)\n 36 renderer.stop_rasterizing()\n 37 renderer._rasterizing = False\n---\u003e 39 return draw(artist, renderer, *args, **kwargs)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py:4352](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py#line=4351), in FancyArrowPatch.draw(self, renderer)\n 4348 # FIXME: dpi_cor is for the dpi-dependency of the linewidth. There\n 4349 # could be room for improvement. Maybe _get_path_in_displaycoord could\n 4350 # take a renderer argument, but get_path should be adapted too.\n 4351 self._dpi_cor = renderer.points_to_pixels(1.)\n-\u003e 4352 path, fillable = self._get_path_in_displaycoord()\n 4354 if not np.iterable(fillable):\n 4355 path = [path]\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py:4327](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py#line=4326), in FancyArrowPatch._get_path_in_displaycoord(self)\n 4325 posB = self._convert_xy_units(self._posA_posB[1])\n 4326 (posA, posB) = self.get_transform().transform((posA, posB))\n-\u003e 4327 _path = self.get_connectionstyle()(posA, posB,\n 4328 patchA=self.patchA,\n 4329 patchB=self.patchB,\n 4330 shrinkA=self.shrinkA * dpi_cor,\n 4331 shrinkB=self.shrinkB * dpi_cor\n 4332 )\n 4333 else:\n 4334 _path = self.get_transform().transform_path(self._path_original)\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py:2732](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py#line=2731), in ConnectionStyle._Base.__call__(self, posA, posB, shrinkA, shrinkB, patchA, patchB)\n 2726 path = self.connect(posA, posB)\n 2727 path = self._clip(\n 2728 path,\n 2729 self._in_patch(patchA) if patchA else None,\n 2730 self._in_patch(patchB) if patchB else None,\n 2731 )\n-\u003e 2732 path = self._clip(\n 2733 path,\n 2734 inside_circle(*path.vertices[0], shrinkA) if shrinkA else None,\n 2735 inside_circle(*path.vertices[-1], shrinkB) if shrinkB else None\n 2736 )\n 2737 return path\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py:2710](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/patches.py#line=2709), in ConnectionStyle._Base._clip(self, path, in_start, in_stop)\n 2708 if in_start:\n 2709 try:\n-\u003e 2710 _, path = split_path_inout(path, in_start)\n 2711 except ValueError:\n 2712 pass\n\nFile [~/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/bezier.py:351](/home/preclineu/.conda/envs/graph_svd/lib/python3.11/site-packages/matplotlib/bezier.py#line=350), in split_path_inout(path, inside, tolerance, reorder_inout)\n 348 from .path import Path\n 349 path_iter = path.iter_segments()\n--\u003e 351 ctl_points, command = next(path_iter)\n 352 begin_inside = inside(ctl_points[-2:]) # true if begin point is inside\n 354 ctl_points_old = ctl_points\n\nStopIteration:\n\n### Expected outcome\n\nEither a more descriptive error that the annotation arrow falls outside the axes limits or the image:\n\n\n### Additional information\n\nThis behaviour is quite erratic because the plot works fine if I 1) use different values for r, 2) comment the ax.set_rticks(...) line, 3) comment ax.annotate(...), 4) comment ax.scatter(an_theta, an_r), etc. The stacktrace seems to imply that the error occurs when the annotation arrow is being drawn.\n\n[Someone on SO](https://stackoverflow.com/questions/79382801/why-is-there-a-stopiteration-error-for-too-many-items-in-matplotlib-polar-plot?noredirect=1#comment139994674_79382801) suggested that the problem might be due to the Axes limits being set when setting the rticks. Indeed, `ax.set_rlim(0, 1)` produces the expected plot. However, I'd then expect `ax.set_rticks([0, 1, 2, 3])` to also make it work, but that does not seem to be the case.\n\n### Operating system\n\nAlmalinux 8.6\n\n### Matplotlib Version\n\n3.7.1\n\n### Matplotlib Backend\n\nmodule://matplotlib_inline.backend_inline\n\n### Python version\n\n3.11.4\n\n### Jupyter version\n\n4.2.5\n\n### Installation\n\nconda","author":{"url":"https://github.com/Valkje","@type":"Person","name":"Valkje"},"datePublished":"2025-01-24T17:28:49.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":2},"url":"https://github.com/29516/matplotlib/issues/29516"}
| 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:a171d65c-502b-3180-a250-4b2da4a18338 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | AFA0:32604D:939349:C925B2:6A52011F |
| html-safe-nonce | da8878302d9e3c413d8568007e151d83a27f59e7e47ad90f45b198690b89b878 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBRkEwOjMyNjA0RDo5MzkzNDk6QzkyNUIyOjZBNTIwMTFGIiwidmlzaXRvcl9pZCI6IjY0OTE1MTY1NTMzODkwMTUzMjciLCJyZWdpb25fZWRnZSI6ImlhZCIsInJlZ2lvbl9yZW5kZXIiOiJpYWQifQ== |
| visitor-hmac | fc1e09018e0cd4f5180b104e53bccdec2876a603729e5b1c384a90717297eb38 |
| hovercard-subject-tag | issue:2809973927 |
| 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/29516/issue_layout |
| twitter:image | https://opengraph.githubassets.com/2a93108a69e96969ee236439dfd3bf32f6fbe46be0e859ddd10c084d54941aa4/matplotlib/matplotlib/issues/29516 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/2a93108a69e96969ee236439dfd3bf32f6fbe46be0e859ddd10c084d54941aa4/matplotlib/matplotlib/issues/29516 |
| og:image:alt | Bug summary I am trying to create a polar plot of some data, with an annotation arrow pointing towards some other point in the plot. However, I get a StopIteration, presumably because of setting th... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | Valkje |
| 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