Title: [Bug]: Overflow of 16-bit integer in Agg renderer causes PolyCollections to be drawn at incorrect locations · Issue #23826 · matplotlib/matplotlib · GitHub
Open Graph Title: [Bug]: Overflow of 16-bit integer in Agg renderer causes PolyCollections to be drawn at incorrect locations · Issue #23826 · matplotlib/matplotlib
X Title: [Bug]: Overflow of 16-bit integer in Agg renderer causes PolyCollections to be drawn at incorrect locations · Issue #23826 · matplotlib/matplotlib
Description: Bug summary Because the pixel x coordinates of scanline cells are casted from 32-bit integers to 16-bit ones in Agg (this line), some polygons that are outside the drawing area may actually be drawn at an incorrect location if they are f...
Open Graph Description: Bug summary Because the pixel x coordinates of scanline cells are casted from 32-bit integers to 16-bit ones in Agg (this line), some polygons that are outside the drawing area may actually be draw...
X Description: Bug summary Because the pixel x coordinates of scanline cells are casted from 32-bit integers to 16-bit ones in Agg (this line), some polygons that are outside the drawing area may actually be draw...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/23826
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"[Bug]: Overflow of 16-bit integer in Agg renderer causes PolyCollections to be drawn at incorrect locations","articleBody":"### Bug summary\n\nBecause the pixel x coordinates of scanline cells are casted from 32-bit integers to 16-bit ones in Agg ([this line](https://github.com/matplotlib/matplotlib/blob/3b79f63980c767fabc59ec5ba267818d8b4b5671/extern/agg24-svn/include/agg_scanline_p.h#L96)), some polygons that are outside the drawing area may actually be drawn at an incorrect location if they are far enough from the viewport so that the 16-bit integer used for actual drawing overflows and the value happens to be inside the drawing area.\n\n### Code for reproduction\n\n```python\nimport matplotlib.pyplot as plt\r\nimport matplotlib\r\nmatplotlib.use('TkAgg')\r\n\r\n# Create a 120x120 px figure\r\nfig = plt.figure(figsize=(120, 120), dpi=1)\r\n# Add axis that fills the whole figure\r\nax = fig.add_axes([0, 0, 1, 1])\r\nax.axis('off')\r\n# Plot one fill_between at x, y = 0, width = 100 and height = 50\r\nax.fill_between([0, 100], 0, 50, color='r')\r\n# Plot another fill_between at x = 65536, y = 50, width=100 and height = 50\r\n# 65536 causes the 16-bit integer to overflow so that the coordinate becomes actually 0\r\nax.fill_between([2 ** 16, 2 ** 16 + 100], 50, 100, color='b')\r\n# Set limits to ensure that one pixel in the rasterized image corresponds to one unit in the axis\r\nax.set_xlim(-10, 110)\r\nax.set_ylim(-10, 110)\r\n# Agg has the bug, Pdf does not\r\nplt.savefig('bug.png', dpi=1)\r\nplt.savefig('nobug.pdf', dpi=1)\r\nplt.show()\n```\n\n\n### Actual outcome\n\nThe PolyCollections are both drawn in the image, even though they are 65536 units apart and the x axis goes from -10 to 110.\r\n\r\n\n\n### Expected outcome\n\nThere should only be the red rectangle, as in this PDF.\r\n[nobug.pdf](https://github.com/matplotlib/matplotlib/files/9525611/nobug.pdf)\r\n\n\n### Additional information\n\nI debugged this quite a bit, and turns out it is a bit tricky to replicate this. The PolyCollections need to be able to fit in the axes completely so that the optimized `draw_markers` function [is called](https://github.com/matplotlib/matplotlib/blob/3b79f63980c767fabc59ec5ba267818d8b4b5671/lib/matplotlib/collections.py#L406). Then, inside Agg, transforms are applied so that pixel coordinates are calculated. These coordinates are fine, as they use 32-bit integers. However, when Agg draws the scanlines, it converts the coordinates to 16-bit integers. If the axis is zoomed in enough and everything lines up just right, some points that have very high positive or very high negative pixel coordinates may appear in the viewport because the int16 conversion causes the 16-bit coordinate to over- or underflow and to be inside the viewport. An obvious fix could be to use int32 instead of int16 while drawing, but I don't know if that's possible or if matplotlib is even the right place to report, as this bug seems to be in Agg code. The original figure where I discovered this had many fill_betweens, and when zoomed in, some fill_betweens from earlier or later in the data would appear.\r\n\r\nNote that at least on my machine, the figure that is shown in the window might not have the bug present, but the saved PNG file should have it.\r\n\r\nI checked also the main branch (version `3.6.0.dev3132+gf8cf0ee5e7`), and it has the bug.\n\n### Operating system\n\nProbably anything where Agg runs (verified on RHEL8 and Windows)\n\n### Matplotlib Version\n\n3.5.3\n\n### Matplotlib Backend\n\nQtAgg\n\n### Python version\n\n3.9.13\n\n### Jupyter version\n\n_No response_\n\n### Installation\n\nconda","author":{"url":"https://github.com/Exploder98","@type":"Person","name":"Exploder98"},"datePublished":"2022-09-08T12:24:17.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":6},"url":"https://github.com/23826/matplotlib/issues/23826"}
| 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:43cc70ef-b209-a249-4a0e-7dc9894e863c |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | DC24:26AD97:10AF0A3:165827B:6A529B8D |
| html-safe-nonce | bb0f13f019ef08cf894e8f6d004e66c200a6604e5cab4d4b7ed76b6a8b2c1c5c |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEQzI0OjI2QUQ5NzoxMEFGMEEzOjE2NTgyN0I6NkE1MjlCOEQiLCJ2aXNpdG9yX2lkIjoiMTU1ODkwMzY5Mzc3MTk3MTQ2OSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | ddf48caf69972cfc58080deddde57962514d5d6486e9518dd39b75a9369ae919 |
| hovercard-subject-tag | issue:1366212510 |
| 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/23826/issue_layout |
| twitter:image | https://opengraph.githubassets.com/953e29b2dd7122286434141537660086a33197d5887f46a4760f43d85a620e43/matplotlib/matplotlib/issues/23826 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/953e29b2dd7122286434141537660086a33197d5887f46a4760f43d85a620e43/matplotlib/matplotlib/issues/23826 |
| og:image:alt | Bug summary Because the pixel x coordinates of scanline cells are casted from 32-bit integers to 16-bit ones in Agg (this line), some polygons that are outside the drawing area may actually be draw... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | Exploder98 |
| 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 | 07a982c1d40157c619b364352b704c3ce66bb332 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width