When I create a completely fresh conda envirnoment:
conda create --name test ipython matplotlib
and then try to import matplotlib.pyplot
from within ipython, I get the following:
In [1]: import matplotlib.pyplot
In [2]: QXcbConnection: Could not connect to display
Aborted
There is no problem when I run the same in the vanilla python shell. Happens for both py2.7.13 (ipython 5.3.0) and py3.6.1 (ipython 6.0.0).
I don't know whether this is an ipython bug or a conda bug, so I raised an issue first with anaconda, but I wanted to note it here too.
Can you check that os.environ['DISPLAY']
is the same in IPython as in the vanilla Python shell?
I guess it might be matplotlib picking a different backend, though I'm not sure why it would do that.
Right-- I forgot to mention that I'm running this on a cluster head node that doesn't have a display. So there is no $DISPLAY set (os.environ['DISPLAY']
gives a KeyError
on both shells).
And if I explicitly set the backend to 'agg'
I also don't get the error, but I'd like to avoid having to do that every time I launch ipython and want to import something that imports matplotlib.
Are you using the IPython terminal interface or IPython as a kernel in a Jupyter interface? I think IPython as a kernel sets the MPLBACKEND
environment variable to produce inline plots by default, but that shouldn't happen with IPython in the terminal. And I don't think the inline plots need an X server, anyway. :-/
I was just using the ipython terminal interface. It would seem that if a DISPLAY
is not available then the backend should default to something that doesn't need it, but that doesn't seem to be happening.
@tacaswell any idea why IPython might be affecting the default backend here?
This happens because the default backend for Matplotlib in Anaconda is Qt5. We're considering to change it to Tk to avoid this kind of problems.
Changing to Tk would still have the same problem.
I think it is showing up immediately with IPython vs python because if pyplot is imported inside of IPython it notices and sets up the event loop integration. In the plain prompt you would get an issue eventually when the user tried to make a plot.
I think moving to tk as default would be less than great.
I think moving to tk as default would be less than great.
What do you mean exactly? Do you think it's better for Anaconda to stay with Qt5?
Qt5 is a nicer framework and support hi-dpi screens out of the box, I think going back to Tk would be regression in user experience.
Ok, we are just a bit worried about the notebook running in headless Docker containers. But with Matplotlib 1.5 (I think), the notebook automatically selects inline
as its default backend, right?
That is entirely on the jupyter side.
If the MPLBACKEND
environment variable is not already set, ipykernel sets it to refer to the inline backend. The comments in our source code say that this will affect mpl >= 1.5, and that it takes priority over matplotlibrc but not over explicitly picking a backend in code.
That's really cool! Then I'd say this can be closed.
The OP can simply set 'agg' as Matplotlib's default backend in his matplotlibrc to avoid this error.
Re-reading this, I notice that it was originally about terminal IPython, not the kernel. What I said above about setting MPLBACKEND does not apply to terminal IPython.
I'll close this now because I don't think what's reported is a bug in IPython. Maybe it's up to the user to configure a headless backend, or maybe MPL's "inside IPython" check should also check whether it's in a headless environment. Either way, I don't think there's anything IPython can do to fix it.
Feel free to keep using this issue as a place to discuss it, though.
Yes, it does seem clear that it is not an ipython bug. I would think that MPL should make the checks to allow someone to launch an ipython shell and import matplotlib.pyplot, and have that not crash, without having to change any matplotlibrc options or explicitly set the backend.
@timothydmorton The issue is telling the difference between "The user just asked to use a GUI backend, but they only sorta-meant it and we should fall back to Agg" vs "The user just asked to use a GUI backend, we can not because there is no X-sever running so we should let them know" from a string input. The trade off has historically been in favor of the interactive users and preventing the "no plot showed up" bug and letting the "I can not use an interactive backend on a headless server" bug happen because in the later case the user gets a clear error as to what is wrong.
There was some discussion recently about how to support "which ever Qt flavor is installed" as a backend and how to do backend fallbacks, but it gets a tricky in general because GUI frameworks tend to step on each other's toes if you import them simultaneously.
I am also effected by this issue, and I cannot think of a good work around besides using regular python instead of ipython.
@russelljjarvis it's a minor annoyance, but if the first command you run when you start up ipython is import matplotlib; matplotlib.use('agg')
then ipython should work for you.
Yes:
import matplotlib; matplotlib.use('agg')
Is the first command I run, but I still get:
In [1]: QXcbConnection: Could not connect to display :0
Aborted
After the program has hit an error, and usually I would be left with a prompt to debug and monkey patch.
I invoke python with ipython -i file_name.py
after first running: ipcluster start -n 8 --profile=default &
Where the first line of file_name is import matplotlib; matplotlib.use('agg')
I wonder if running ipcluster might be causing the problems.
There's a solution using environment variables available here:
Setting export QT_QPA_PLATFORM='offscreen'
in my .bash_profile
worked for me.
A colleague recently suggested the same thing. In the context of Docker your statement would be:
ENV QT_QPA_PLATFORM offscreen
. I am effectively testing that now.
I am getting the same error:
Setting export QT_QPA_PLATFORM='offscreen'
changed the error message to:
(python:17399): Gtk-WARNING **: cannot open display:
solution in notebook directly
import os
os.environ['QT_QPA_PLATFORM']='offscreen'
As a late-ish follow up, as of Matplotlib 3.0 we now support automatic backend selection and will not try to use a GUI backend on a headless server (but will still respect an rcparams file that asks us to).
This answer https://unix.stackexchange.com/questions/192642/wkhtmltopdf-qxcbconnection-could-not-connect-to-display
Resolved after install manually
"conda update matplotlib" fixed the problem for me.
export QT_QPA_PLATFORM='offscreen'
As a late-ish follow up, as of Matplotlib 3.0 we now support automatic backend selection and will not try to use a GUI backend on a headless server (but will still respect an rcparams file that asks us to)
Matplotlib 3.1 cannot support automatic backend, we need to manually set 'Agg' .
This happens because the default backend for Matplotlib in Anaconda is Qt5. We're considering to change it to Tk to avoid this kind of problems.
where i can change this one?
This is my error after setting export QT_QPA_PLATFORM=offscreen
[tb571@da02 ~]$ jupyter console --kernel slicer-4.11
qt.qpa.plugin: Could not find the Qt platform plugin "offscreen" in ""
This application failed to start because no Qt platform plugin could be initialized. Reinstalling the application may fix this problem.
After setting QT_QPA_PLATFORM='offscreen'
the imports of matplotlib and fastai libraries run.
However, plt.figure() or any other command outputting a plot raises the following errors:
This plugin does not support propagateSizeHints()
This plugin does not support raise()
I am getting this error as well
Most helpful comment
There's a solution using environment variables available here:
Setting
export QT_QPA_PLATFORM='offscreen'
in my.bash_profile
worked for me.