Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

matplotlibrc: is there a way to specify "backend" as either "Qt5Agg | Qt4Agg" (whatever is installed)? #8613

Closed
megies opened this issue May 12, 2017 · 20 comments

Comments

@megies
Copy link
Contributor

megies commented May 12, 2017

I have loads of conda environments in parallel, some of which have Qt4 installed and some have Qt5. I used to have backend : Qt4Agg in my ~/.config/matplotlib/matplotlibrc, but nowadays this will get me errors when I'm in one of the Qt5-environments.

Ideally I would like to be able to specify backend : QtAgg and it should use either Qt5 or Qt4, whatever is available ad hoc.

I had a look at the backend selection stuff, but couldn't find how to do it. I'd propose to come up with a PR if somebody could give me a short tip, where to implement such a switch..

@tacaswell
Copy link
Member

I think this is a very good idea.

The places to fix this would be:

  • rcsetup.py to allow the new string for the backend
  • adding another epicycle to lib/matplotlib/backends/qt_compat.py to keep track of when it falls back and update the rcParams accordingly.

@tacaswell tacaswell added this to the 2.1 (next point release) milestone May 12, 2017
@megies
Copy link
Contributor Author

megies commented May 12, 2017

Alright, thanks for directions, I'll have a look. Appropriate base branch would be master, I guess?

@tacaswell
Copy link
Member

Yeah, this would go in for 2.1, too big of a change for a patch release.

@megies
Copy link
Contributor Author

megies commented May 12, 2017

So if I just add it in those two places mpl complains because it tries to lookup backend_qtagg.py.

Should I put a dummy backend_qtagg.py in place that imports from either backend_qt5agg.py or backend_qt4agg.py or am I missing something?

@tacaswell
Copy link
Member

Sorry, I missed a step in how the backend lookup works 😞 🐑 .

Putting in a backend_qtagg.py which imports qt_compat (which should update the rcparams to be the Qt4 or Qt5) and then imports from the correct backend is a reasonable solution.

The other option I see is to hack at pylab_setup in backendends/__init__.py to special-case the qt backeds, but that seems worse.

@anntzer
Copy link
Contributor

anntzer commented May 13, 2017

What about letting backend just be a list of tentative backends that are tried one after the other?

@tacaswell
Copy link
Member

@anntzer I like that idea better than what I suggested.

@megies
Copy link
Contributor Author

megies commented May 15, 2017

Sounds good to me, I guess the process of trying one backend or the other doesn't hamper selecting a usable backend anymore? Back in the old days, selecting a backend sometimes used to be a one-shot operation.. e.g. when running some server scripts it was essential to select "AGG" (import matplotlib; matplotlib.use("AGG")) at the top of the file before any pyplot imports because switching was often not possible anymore once one backend was imported..?

@WeatherGod
Copy link
Member

WeatherGod commented May 15, 2017 via email

@megies
Copy link
Contributor Author

megies commented May 15, 2017

Thanks for the feedback @WeatherGod. This kind of backs my unease with specifying backend in RC as a list. Furthermore changing it to be a list instead of a string for one backend might have other side effects (backwards compatibility etc.).

So maybe it would be least invasive to add a stub backend_qtagg.py that sets either Qt5 or Qt4..

But I'll wait for more opinions for a while..

@anntzer
Copy link
Contributor

anntzer commented May 15, 2017

One of the caveats I would have with the suggested approach is that there
exists code in the wild (and possibly within mpl itself, I can't remember),
that queries the list of imported modules so far and figures out which GUI
toolkit to use based on what it finds in that list. If we have failed
attempts to import a toolkit, the failed imports might leave behind partial
imports in the tree, which may confuse some of those algorithms.

I am almost certain such approaches are already broken -- one can e.g. manually import tkinter while the backend is Qt5Agg. The correct approach is (currently) to check the value of mpl.rcParams["backend"].

I think a backcompatible way is to add a plural form rcParams["backends"] which specifies a list of backends, tries to set them up one at a time, and, whenever one succeeds, sets rcParams["backend"] accordingly. This requires no backend-switching as the algorithm will stop as soon as it successfully sets a backend.

@tacaswell
Copy link
Member

tacaswell commented May 15, 2017

I was thinking we accept either a list or a string for rcparams['backend']. The place where the backend lock-in happens is in pyplot due to the things returned from pylab_setup.

The multiple backends should be tried in pylab_setup (basically go down the backend list until one of them imports cleanly), return the functions, and then you are locked in.

[Edited to add the missing sentence]

@anntzer
Copy link
Contributor

anntzer commented May 15, 2017

Actually that'd work too. If you want to sniff the actual backend, you read rcParams["backend"] and if it's a list, it means that matplotlib hasn't made its choice yet?

@WeatherGod
Copy link
Member

WeatherGod commented May 15, 2017 via email

@WeatherGod
Copy link
Member

WeatherGod commented May 15, 2017 via email

@anntzer
Copy link
Contributor

anntzer commented May 15, 2017

the environment variable should just force the backend.

@anntzer
Copy link
Contributor

anntzer commented Jun 20, 2017

Note that specifying the backends as a list would also solve issues such as #8518 ("the default backend is chosen at build time, and sometimes defaults to a non-interactive backend"): one can just default to e.g. ["macosx", "qt5agg", "qt4agg", ...] (basically copy-pasting the order used in setup.py for backend priority).

@tacaswell tacaswell modified the milestones: 2.2 (next next feature release), 2.1 (next point release) Jul 30, 2017
@anntzer
Copy link
Contributor

anntzer commented Sep 19, 2018

Improved, but not closed, by #9795 (there's a fixed fallback list now).

@timhoffm
Copy link
Member

Closing because Qt4 is deprecated since Matplotlib 3.3.

@QuLogic
Copy link
Member

QuLogic commented Jul 14, 2020

I'm not sure this is specifically about Qt4 vs Qt5. However, we have automatic backend selection now, so you could just leave out a backend from matplotlibrc and it would pick whichever one you have in your conda environment.

@story645 story645 removed this from the future releases milestone Oct 6, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants