Title: Backend switching by anntzer · Pull Request #9795 · matplotlib/matplotlib · GitHub
Open Graph Title: Backend switching by anntzer · Pull Request #9795 · matplotlib/matplotlib
X Title: Backend switching by anntzer · Pull Request #9795 · matplotlib/matplotlib
Description: This is the followup to #9551 (backend loading refactor), and includes it (so it would make sense for #9551 to be merged first). This PR removes the ambiguous behavior of matplotlib.use, which was, up to now, documented as follows: This function must be called before importing pyplot for the first time; or, if you are not using pyplot, it must be called before importing matplotlib.backends. If warn is True, a warning is issued if you try and call this after pylab or pyplot have been loaded. "In certain black magic use cases, e.g. pyplot.switch_backend, we are doing the reloading necessary to make the backend switch work (in some cases, e.g., pure image backends) so one can set warn=False to suppress the warnings.) Instead, matplotlib.use now works just fine as long as an event loop has not started yet (i.e. an interactive window popped up), or when switching to a noninteractive backend, or to an interactive backend compatible with the current event loop (e.g. gtk3agg -> gtk3cairo); in all other cases, an exception is raised. This means, for example, that one can write from matplotlib import pyplot as plt; plt.rcParams["backend"] = "foo"; ... instead of having to do a separate import of matplotlib. Moreover, it is now possible to set rcParams["backend"] to a list of candidate backends; they will simply be tested one at a time until one succeeds. If pyplot is already loaded, the value in rcParams["backend"] is immediately replaced by the successful candidate. If pyplot is not loaded yet, rcParams["backend"] will keep hold of the list of candidates until pyplot is loaded. This is a documented change of behavior (users should import pyplot to force backend resolution). (Alternatively the list could be shoved into a new, separate rcParam, but little would be gained because rcParams["backend"] would then hold an incorrect value until backend resolution). Another change of behavior is that the matplotlib.backends.backend global variable has been removed, again in favor of rcParams["backend"] as single truth point: it was too difficult to properly keep matplotlib.backends.backend in sync, especially at import time when that module may not have been imported yet. (Exception: I don't have a Mac available to figure out the relevant fixes for the OSX backend, but hopefully another contributor can help here. See _get_current_event_loop.) Edit: Now also working on OSX, see comment below. A major advantage of such a scheme is that we can now just ship a default matplotlibrc which lists all buitin backends in preference order (backend: osx, qt5agg, qt4agg, gtk3agg, ...). Currently, this list is evaluated at build time (by testing which GUI toolkit is importable), which causes two major problems: 1) the import of the GUI toolkits need to happen in separate processes, which means that setup.py relies on multiprocessing(!); for example, this appears to confuse conda-build (see comment in ci/conda_recipe/meta.yaml); 2) the built list is useless anyways unless 1) the end user is doing the build, rather than a central packager (the end user may have a different list of installed GUI toolkits...) and 2) the end user never adds or removes a new GUI toolkit. Here, I can instead completely strip out the relevant part of setupext.py, greatly simplifying it. The backend_fallback rcParam likewise becomes obsolete, although this PR does not remove it (this rcParam can easily go through a normal deprecation route). I also removed the interactive backends API docs because the shimming (to allow them to be imported in a headless buildbot) was insufficient to support this PR's implementation. Proposed fix at #9708 (comment). (But note that they were incomplete anyways...) Closes #3679, #6739, #8613, #9017 (comment); sort-of #3466 (which is perhaps more a doc issue...). Some comments to try clarifying the implementation: matplotlib.use only supports a single argument (not a list of candidate backends) because we want to keep use(...); rcdefaults() working: this implies that use(...) must overwrite the default backend (in rcParamsDefault, and likewise rcParamsOrig), to a single fixed value. setting multiple entries in rcParams["setup"] defers to pyplot.switch_backends, which itself defers to backends.pylab_setup. Once the correct candidate is found, backends.pylab_setup sets the single entry in rcParams["setup"].
Open Graph Description: This is the followup to #9551 (backend loading refactor), and includes it (so it would make sense for #9551 to be merged first). This PR removes the ambiguous behavior of matplotlib.use, which was,...
X Description: This is the followup to #9551 (backend loading refactor), and includes it (so it would make sense for #9551 to be merged first). This PR removes the ambiguous behavior of matplotlib.use, which was,...
Opengraph URL: https://github.com/matplotlib/matplotlib/pull/9795
X: @github
Domain: github.com
| route-pattern | /:user_id/:repository/pull/:id/files(.:format) |
| route-controller | pull_requests |
| route-action | files |
| fetch-nonce | v2:f17b675c-b0d2-8da2-7c19-2d8e4cf5975b |
| current-catalog-service-hash | ae870bc5e265a340912cde392f23dad3671a0a881730ffdadd82f2f57d81641b |
| request-id | E45A:39F98C:C19E5C:11950E2:6A54B9A3 |
| html-safe-nonce | b7e926a079d497a7c52898e40eb78e77d56592803346b80d98b5ed6ddf609534 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFNDVBOjM5Rjk4QzpDMTlFNUM6MTE5NTBFMjo2QTU0QjlBMyIsInZpc2l0b3JfaWQiOiI1NjM4MTQ5NTg3MjQ2Mjk5NTU1IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | d91bdf58e556483e6cf21ff280f2e475989edaff30996f4a86b67a5089cb283c |
| hovercard-subject-tag | pull_request:152960954 |
| 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/9795/files |
| twitter:image | https://avatars.githubusercontent.com/u/1322974?s=400&v=4 |
| twitter:card | summary_large_image |
| og:image | https://avatars.githubusercontent.com/u/1322974?s=400&v=4 |
| og:image:alt | This is the followup to #9551 (backend loading refactor), and includes it (so it would make sense for #9551 to be merged first). This PR removes the ambiguous behavior of matplotlib.use, which was,... |
| og:site_name | GitHub |
| og:type | object |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| 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 | 5d343e1152573ef294b28f54e4a14fb5fdb3a5a1 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width