-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
[ENH]: Does pyplot need to call switch_backend #22739
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
Comments
The fact that pyplot triggers the backend creation is documented, and so is
the fact that this causes side-effects.
EDIT: At least, we used to extensively document this... I was about to post
a bunch of links from the docs talking about this, but now I can't find the
relevant information. The best I can get is
https://matplotlib.org/stable/users/explain/interactive.html
That being said, work is ongoing to defer the backend initialization to
later points in the figure lifetime. Perhaps you can help with that effort?
…On Wed, Mar 30, 2022 at 11:29 PM Mark Harfouche ***@***.***> wrote:
Problem
It seems that simply importing pyplot can have serious effects on what
backends are chosen, and how they interact with one and other.
In
https://github.com/matplotlib/matplotlib/blob/da9533d507c1f06ceee5078c9cbbd99897809d31/lib/matplotlib/__init__.py#L1137
They say that simply
from matplotlib import pyplot
can trigger setting the default backend.
This is somewhat frustrating for people who use interactive sessions.
Running the code
from matplotlib import pyplot
import matplotlib
matplotlib.use("WxAgg")
all at once will work in ipython (from the terminal). But running it one
line at a time, won't.
This is somewhat strange.
Now that things like __getattr__ exist, would be possible to further
delay setting the default backend?
The issue arises when you want to build an application, and other people's
code might be imported before yours. You are then at their mercy to not set
the backend (implicitly!) before you set yours.
Proposed solution
No solution. I'm sure there is some strange historic thing I'm missing.
Honestly, you created a great API with pyplot. People use it to get
colormaps, and for all sorts of things.
XREF: DeepLabCut/DeepLabCut#1730
<DeepLabCut/DeepLabCut#1730>
—
Reply to this email directly, view it on GitHub
<#22739>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AACHF6CHT52IKVM6YRCD2RTVCULZXANCNFSM5SD7ZBWA>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
ok, understood. I didn't know if patches would be welcome that would defer that. Is there an API that application developers can use that is independent of the chosen backend? That is, they would specify their own handles/backend name and matplotlib will forcibly use that? |
Deferring backed selection has been implemented in #22005, but is not yet released.
I'm not the backend expert here, but I'm not aware of a reasonably simple way to do this. General question: Is there a reason that we need global exclusive backend state and cannot have a per-figure backend setting? |
I don't know - is it really worth the trouble to allow multiple GUI backends to run at the same time? I could see us allowing one GUI to be closed and a different one opened after the GUI is closed, but I'm not sure its a good idea for one python process to have multiple GUI frameworks running at the same time? We probably should revisit the roadmap for https://github.com/matplotlib/mpl-gui |
Well... I feel like it might be address in the next release. |
Can't wait! |
I'm not entirely sure. It is kinda hard to compile matplotlib and backporting the patch wasn't super easy. There still seems to be eager code in: so i really wnat to have the time to test before saying it is fixed. |
The comment I referred to in the init file seems suspicious now too. |
You cannot have e.g. both qt and tk running as they'll fight over https://docs.python.org/3/c-api/veryhigh.html#c.PyOS_InputHook. You could allow e.g. qtcairo + qtagg or any interactive backend + any noninteractive backend, but I'm not sure it's worth the engineering... |
I can if I have different processes 😝 |
matplotlib/lib/matplotlib/pyplot.py Lines 2246 to 2250 in d8ede1a
says:
then set the backend to "automatic" and let the later machinery sort out detecting which one is running and doing the correct selection then. |
matplotlib/lib/matplotlib/__init__.py Lines 1137 to 1155 in da9533d
This code is saying "if the user explicitly called I am morbidly curious why it was going wrong before but I do think it is fixed.
Where are you trying to backport it to? If you can compile skimage, I would also expect Matplotlib to compile "out of the box" as well... |
And thank to #22733 which just got merged
will now get you nightlies! |
Slight correction to that install command. To get everything to work properly with dependencies you need to run:
|
Touchée . I guess I'm using conda for most environment management. I'll give it a try in a few hours. |
You might be interested in my book, "Interactive Applications using Matplotlib". It is a little out of date now (published almost 7 years ago!), but many of the principles are still true. In it, it describes how to embed a figure as a widget in an existing GUI application. It also shows how to embed GUI widgets into a regular matplotlib figure window. Furthermore, it also talks about some of the GUI-agnostic widgets that are available so that you can have an application that'll work in just about any interactive environment. |
I'm not going to say I can't get it to compile from source, but I am going to say that for my conda environment, I tried:
and it resulted in:
Kinda just as hard as I expected it to be (i.e. not to work on the first try). The link provided on anaconda installed successfully. Finally, it does resolve the problem of allowing you to select the WxAgg backend. I then uninstalled it, and reinstalled the version from conda-forge, and it seems to work! Thanks all! |
Oh, that makes sense 😞 . We build our own freetype pinned to a very old version (so the tests will pass because every version of freetype moves the text around a tiny bit) but conda provides a newer one. I suspect at runtime you ended up with crossed libraries.... I will not claim to understand what the wheel is doing under the hood to make it work though! |
@tacaswell thank you for the hint about freetype. using a slightly modified build script from conda-forge Time for me to sleep. Goodnight |
Problem
It seems that simply importing pyplot can have serious effects on what backends are chosen, and how they interact with one and other.
In
matplotlib/lib/matplotlib/__init__.py
Line 1137 in da9533d
They say that simply
can trigger setting the default backend.
This is somewhat frustrating for people who use interactive sessions.
Running the code
all at once will work in ipython (from the terminal). But running it one line at a time, won't.
This is somewhat strange.
Now that things like
__getattr__
exist, would be possible to further delay setting the default backend?The issue arises when you want to build an application, and other people's code might be imported before yours. You are then at their mercy to not set the backend (implicitly!) before you set yours.
Proposed solution
No solution. I'm sure there is some strange historic thing I'm missing.
Honestly, you created a great API with pyplot. People use it to get colormaps, and for all sorts of things.
XREF: DeepLabCut/DeepLabCut#1730
The text was updated successfully, but these errors were encountered: