Title: `Axes3D.plot_surface`: Allow masked arrays and `NaN` values by tomneep · Pull Request #20725 · matplotlib/matplotlib · GitHub
Open Graph Title: `Axes3D.plot_surface`: Allow masked arrays and `NaN` values by tomneep · Pull Request #20725 · matplotlib/matplotlib
X Title: `Axes3D.plot_surface`: Allow masked arrays and `NaN` values by tomneep · Pull Request #20725 · matplotlib/matplotlib
Description: PR Summary Closes #487 Closes #4941 Closes #8222 Closes #12395 Closes #16470 This is my third attempt at solving the issues with using masked arrays in Axes3D.plot_surface, previous attempts are #18114 and #20646. Hopefully it is third time lucky. I got the impression that the feedback on #18114 was reasonably positive but this approach solves more issues and also behaves like contour with corner_mask=True which was a preference expressed by @ianthomas23. The suggestion from #20646 was that it would be better to deal with NaNs before we get to Poly3DCollection.do_3d_projection which is called every time we adjust an interactive figure. I've gone "all in" on this PR and removed the warning about not supporting NaNs and added masked array support, if you prefer to take this step-by-step e.g. removing the masked array part or keeping the NaN warning, then let me know, and I'll happily change. There are no tests yet, once I've had some feedback on this I'll add some based on the issues that this closes. Examples of the issues that this PR solves (along with the code to make them) are below. I didn't add the example from #8222 which loads a large dataset but the before and after are visually the same as the examples shown in #20646. Examples before this PR Examples after this PR Code for examples import matplotlib import matplotlib.pyplot as plt import numpy as np fig, axes = plt.subplots( nrows=2, ncols=2, figsize=(10, 10), subplot_kw={"projection": "3d"}, constrained_layout=True, ) # 487 x, y = np.mgrid[1:10:1, 1:10:1] z = x ** 3 + y ** 3 - 500 z = np.ma.masked_array(z, z < 0) plot_opts = dict(rstride=1, cstride=1, linewidth=0, cmap="inferno") axes[0, 0].plot_surface(x, y, z, **plot_opts) axes[0, 0].view_init(35, -90) axes[0, 0].set(title="Issue #487") # 4941 x, y = np.mgrid[-1:1:0.05, -1:1:0.05] z = (x ** 2 + y ** 2) + 0.01 z[10:20, 10:20] = 0.0 masked_array = np.ma.masked_equal(z, 0.0) palette = plt.get_cmap("gray").copy() palette.set_over("g", 1.0) palette.set_under("b", 1.0) palette.set_bad("r", 1.0) plot_opts = dict(rstride=1, cstride=1, cmap=palette, vmin=-1, vmax=1) axes[0, 1].plot_surface(x, y, masked_array, **plot_opts) axes[0, 1].view_init(35, -90) axes[0, 1].set(title="Issue #4941") # 12395 z = (1 - y / x).clip(min=-5, max=5) # place NaNs at the discontinuity pos = np.where(np.abs(np.diff(z, axis=0)) >= 5.0) z[pos] = np.nan plot_opts = dict(rstride=1, cstride=1, cmap="coolwarm", antialiased=False) axes[1, 0].plot_surface(x, y, z, **plot_opts) axes[1, 0].set(title="Issue #12395") #16470 x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] y = [1, 2, 3, 4, 5, 6, 7, 8] x, y = np.meshgrid(x, y) nan = np.nan matrix = np.array( [ [nan, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0], [nan, 1.0, 2.0, 3.0, 4.0, 4.0, 4.0, 3.0, 2.0, 1.0, 1.0], [nan, nan, 4.0, 5.0, 6.0, 8.0, 6.0, 5.0, 4.0, 3.0, nan], [nan, nan, 7.0, 8.0, 11.0, 12.0, 11.0, 8.0, 7.0, nan, nan], [nan, nan, 8.0, 9.0, 10.0, 16.0, 10.0, 9.0, 10.0, 7.0, nan], [nan, nan, nan, 12.0, 16.0, 20.0, 16.0, 12.0, 11.0, nan, nan], [nan, nan, nan, nan, 22.0, 24.0, 22.0, 20.0, 18.0, nan, nan], [nan, nan, nan, nan, nan, 28.0, 26.0, 25.0, nan, nan, nan], ] ) z = np.ma.masked_invalid(matrix) normC = matplotlib.colors.Normalize(vmax=z.max(), vmin=z.min()) colors = plt.get_cmap("plasma")(normC(z)) axes[1, 1].plot_surface(x, y, z, facecolors=colors) axes[1, 1].view_init(30, -80) axes[1, 1].set(title="Issue #16470") PR Checklist Has pytest style unit tests (and pytest passes). Is Flake 8 compliant (run flake8 on changed files to check). New features are documented, with examples if plot related. Documentation is sphinx and numpydoc compliant (the docs should build without error). Conforms to Matplotlib style conventions (install flake8-docstrings and run flake8 --docstring-convention=all). New features have an entry in doc/users/next_whats_new/ (follow instructions in README.rst there). API changes documented in doc/api/next_api_changes/ (follow instructions in README.rst there).
Open Graph Description: PR Summary Closes #487 Closes #4941 Closes #8222 Closes #12395 Closes #16470 This is my third attempt at solving the issues with using masked arrays in Axes3D.plot_surface, previous attempts are ...
X Description: PR Summary Closes #487 Closes #4941 Closes #8222 Closes #12395 Closes #16470 This is my third attempt at solving the issues with using masked arrays in Axes3D.plot_surface, previous attempts are ...
Opengraph URL: https://github.com/matplotlib/matplotlib/pull/20725
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:5418cfd2-1d76-0899-ca66-bf1f3825c3e7 |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | 8928:289E91:2EBA7D9:432B4D8:6A55257D |
| html-safe-nonce | 8a911e1abc2630fe3dff343fba764fb79399716697b820ce52804a9a5c47bf26 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4OTI4OjI4OUU5MToyRUJBN0Q5OjQzMkI0RDg6NkE1NTI1N0QiLCJ2aXNpdG9yX2lkIjoiNzA1MjU2MDE4OTg3MTE3MDk0MSIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 812a8fa7ad86468a3b94b81c2dbd3527a22d1b4def9ca65aab6e08ae711591e6 |
| hovercard-subject-tag | pull_request:696141053 |
| github-keyboard-shortcuts | repository,pull-request-list,pull-request-conversation,pull-request-files-changed,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/matplotlib/matplotlib/pull/20725/files |
| twitter:image | https://avatars.githubusercontent.com/u/17545360?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/17545360?s=400&v=4 |
| og:image:alt | PR Summary Closes #487 Closes #4941 Closes #8222 Closes #12395 Closes #16470 This is my third attempt at solving the issues with using masked arrays in Axes3D.plot_surface, previous attempts are ... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | 682d273eacb2ac51680c6eb9c0b270f029f7ce74c32090f319083c34497e28a5 |
| turbo-cache-control | no-preview |
| diff-view | unified |
| 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 full-width |
| disable-turbo | true |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 358dd24ad7465d20e3fae729b5b169d35b0dd7f8 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width