Title: "Fillable" markers should be equal-area or equal-width for a given `markersize` · Issue #16623 · matplotlib/matplotlib · GitHub
Open Graph Title: "Fillable" markers should be equal-area or equal-width for a given `markersize` · Issue #16623 · matplotlib/matplotlib
X Title: "Fillable" markers should be equal-area or equal-width for a given `markersize` · Issue #16623 · matplotlib/matplotlib
Description: Bug report Currently, "markersize" means something quite heterogeneous for each different marker (see below). We could easily make it mean the same thing by scaling the "base" size of each marker's path so that it has unit area. This wou...
Open Graph Description: Bug report Currently, "markersize" means something quite heterogeneous for each different marker (see below). We could easily make it mean the same thing by scaling the "base" size of each marker's...
X Description: Bug report Currently, "markersize" means something quite heterogeneous for each different marker (see below). We could easily make it mean the same thing by scaling the "base" s...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/16623
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"\"Fillable\" markers should be equal-area or equal-width for a given `markersize`","articleBody":"\u003c!--To help us understand and resolve your issue, please fill out the form to the best of your ability.--\u003e\r\n\u003c!--You can feel free to delete the sections that do not apply.--\u003e\r\n\r\n### Bug report\r\n\r\nCurrently, \"markersize\" means something quite heterogeneous for each different marker (see below). We could easily make it mean the same thing by scaling the \"base\" size of each marker's path so that it has unit area. This would have the upside of making plots with a constant `markersize` across different markers look perceptually uniform. And would fix a few ancient issues, like issue #1099.\r\n\r\nAn alternative would be to have markers be unit \"width\" (see below), which would fix all but the pentagon markers to at least be slightly more uniform. We could then use the actual areas of the unit marker sizes as a simple scaling factor in `Axes.scatter` to fix #1099. \r\n\r\n\u003c!--A short 1-2 sentences that succinctly describes the bug--\u003e\r\n\r\n**Code for reproduction**\r\n\r\n\u003c!--A minimum code snippet required to reproduce the bug.\r\nPlease make sure to minimize the number of dependencies required, and provide\r\nany necessary plotted data.\r\nAvoid using threads, as Matplotlib is (explicitly) not thread-safe.--\u003e\r\n\r\n```python\r\nimport numpy as np\r\nimport matplotlib as mpl\r\nimport matplotlib.pyplot as plt\r\nfor marker in mpl.markers.MarkerStyle.markers:\r\n fig, ax = plt.subplots()\r\n plt.xlim([-0.04, 0.04])\r\n plt.ylim([-0.04, 0.04])\r\n lines = ax.scatter(0, 0, s=100**2, marker=marker, clip_on=False)\r\n plt.title(str(marker))\r\n\r\n origin_px = ax.transData.transform((0,0))\r\n top_right_px = origin_px + np.array([50, 50])\r\n top_right_data = ax.transData.inverted().transform(top_right_px)\r\n ax.plot([-1, 1], [top_right_data[1], top_right_data[1]])\r\n ax.plot([-1, 1], [-top_right_data[1], -top_right_data[1]])\r\n ax.plot([top_right_data[0], top_right_data[0]], [-1, 1])\r\n ax.plot([-top_right_data[0], -top_right_data[0]], [-1, 1])\r\n```\r\n\r\n**Actual outcome**\r\n\r\n\u003c!--The output produced by the above code, which may be a screenshot, console output, etc.--\u003e\r\nThe `point` is *defined* to be a half-radius `circle`. I guess this is fine.\r\n\r\nThe `pixel` of course has a fixed meaning, so need not be updated.\r\n\r\n\r\nFor several markers, `markersize` means \"width\" or \"height\" (many omitted for clarity, but happy to edit this to include all here for reference):\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\r\n\u003c!--  --\u003e\r\n\r\n\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\r\n\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\u003c!--  --\u003e\r\n\r\n\r\n\r\nFor some markers, `markersize` means \"width of square used to create me\", which seems pretty unexpected after all the above examples otherwise:\r\n\r\n\r\n\r\nAnd for *only some* polygons (notice that there are many full-width triangles in the first list above), `markersize` means \"radius of the circumscribing circle\", which means it neither corresponds to the width/height NOR the area:\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n\r\n**Expected outcome**\r\n\r\n\u003c!--A description of the expected outcome from the code snippet--\u003e\r\n\u003c!--If this used to work in an earlier version of Matplotlib, please note the version it used to work on--\u003e\r\n\r\n\u003c!--By my count, there are basically only two kinds of markers:--\u003e\r\n\r\n\u003c!--1) regular polygons and \"skeletons\" of regular polygons (e.g. '8'/'p', '1')--\u003e\r\n\u003c!--2) \"square-fittable\" shapes. that is, marker shapes where one might have a natural expectation that the base path aligns nicely with a unit square. for example, a--\u003e\r\n\r\nTwo proposals for fixing this: \r\n\r\n1) make all `markersize=1` markers have unit area. This is easy to do by scaling their paths appropriately. The non-fillable markers could be left as-is or scaled to the size at which their \"fillable\" counterpart would have unit area. (e.g. '1' would be scaled so that the equilateral triangle it draws the skeleton of would have unit area, 'x' and '+' would be scaled so that the squares they draw the skeleton of would have unit area).\r\n\r\n2) make all `markersize=1` markers have unit width/height (whichever is larger). This seems more in line with the current \"zeitgeist\" of marker design. It would only require changing a couple of markers:\r\n a) 'd' (thin diamond) and 'D' (diamond) would be scaled to be of unit height instead of \"D\" being made from a rotated unit square (so a factor of 1/sqrt(2)).\r\n b) '8' (octagon) and 'p'/'*' (pentagon/star) would be scaled up slightly to have unit width. Especially for octagon (see above) this would match MUCH better the current conventions for e.g. 'x'/'X'. \r\n c) \"triangle skeletons\" (i.e. `'tri_left'` and friends) should be scaled to be the same width as the `'caret'` family, for consistency.\r\nEvery other marker could remain the same and this convention be matched.\r\n\r\nI am happy to make either of these into a PR (code is written for option 2 already, tbh). However, if we go with option (2), I think we should definitely fix the `s` argument to scatter to actually be a measurement of the area of the marker in px^2, since each marker in that case will still have a different base area measurement (also code already written, tbh).\r\n\r\n**Matplotlib version**\r\n\u003c!--Please specify your platform and versions of the relevant libraries you are using:--\u003e\r\n * Operating system: Debian 9\r\n * Matplotlib version: 3.1.3\r\n * Matplotlib backend (`print(matplotlib.get_backend())`): N/A\r\n * Python version: 3.7\r\n * Jupyter version (if applicable): N/A\r\n * Other libraries: N/A\r\n\r\n\u003c!--Please tell us how you installed matplotlib and python e.g., from source, pip, conda--\u003e\r\n\u003c!--If you installed from conda, please specify which channel you used if not the default--\u003e\r\n\r\n","author":{"url":"https://github.com/brunobeltran","@type":"Person","name":"brunobeltran"},"datePublished":"2020-03-01T23:58:32.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":2},"url":"https://github.com/16623/matplotlib/issues/16623"}
| 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:fece5b8c-6e76-7bae-bfce-86ed813e9dfc |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | AE62:21AE3:2A8D230:3CE5CEE:6A51127D |
| html-safe-nonce | 568a49df8d6738bf6737c93af0db259a5ab7f9ca4cfc061b9e24b6379846f8a8 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBRTYyOjIxQUUzOjJBOEQyMzA6M0NFNUNFRTo2QTUxMTI3RCIsInZpc2l0b3JfaWQiOiIzMjAwNTQwODU1NDUxNTg3MTk3IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | b1919f4edfa704177ce95262323e505e0f362370e94b7fc523f9a6ae47f51890 |
| hovercard-subject-tag | issue:573645364 |
| 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/16623/issue_layout |
| twitter:image | https://opengraph.githubassets.com/4ec6de20d399cf2c79e0b3d40c53ed52f723a32e0c06490cbf184ea89b176285/matplotlib/matplotlib/issues/16623 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/4ec6de20d399cf2c79e0b3d40c53ed52f723a32e0c06490cbf184ea89b176285/matplotlib/matplotlib/issues/16623 |
| og:image:alt | Bug report Currently, "markersize" means something quite heterogeneous for each different marker (see below). We could easily make it mean the same thing by scaling the "base" size of each marker's... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | brunobeltran |
| hostname | github.com |
| expected-hostname | github.com |
| None | b076e100febaa00374cd89239f915d00dd3187f7c68b12bc2b7688181305344d |
| 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 | f9137f6d981cbbfd780af369f80ce890b2d0d2d4 |
| ui-target | canary-1 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width