Reputation: 2667
I am running a simple python script in the server:
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(60)
y = np.random.randn(60)
plt.scatter(x, y, s=20)
out_png = 'path/to/store/out_file.png'
plt.savefig(out_png, dpi=150)
I try to use the command python example.py
in this server which has matplotlib 1.5.1 installed it fails with the error:
Traceback (most recent call last):
File "example.py", line 7, in <module>
plt.scatter(x, y, s=20)
File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 3241, in scatter
ax = gca()
File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 928, in gca
return gcf().gca(**kwargs)
File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 578, in gcf
return figure()
File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/pyplot.py", line 527, in figure
**kwargs)
File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 84, in new_figure_manager
return new_figure_manager_given_figure(num, figure)
File "/home/USER/.virtualenvs/nnet/lib/python2.7/site-packages/matplotlib/backends/backend_tkagg.py", line 92, in new_figure_manager_given_figure
window = Tk.Tk()
File "/usr/local/lib/python2.7/lib-tk/Tkinter.py", line 1810, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
What is happening here?
Upvotes: 248
Views: 472681
Reputation: 2012
Though there is a solution use('Agg')
, someone may be interested in solving x11.
So let's say we have a user ml
, on ubuntu20 with python3...
First, log in as ml
, and write a ml.py
$ cat ml.py
import matplotlib.pyplot as plt
import numpy as np
x = np.random.randn(60)
y = np.random.randn(60)
plt.scatter(x, y, s=20)
out_png = 'out_file.png'
plt.savefig(out_png, dpi=150)
Before run the file, we should set up x11,
$ whoami
ml
$ touch ~/.Xauthority
$ ls .Xauthority
.Xauthority
# only this one key is needed for X11 over SSH
xauth generate :14 . trusted
$ echo $DISPLAY
localhost:14.0
$ xauth list
ml/unix:14 MIT-MAGIC-COOKIE-1 b6a2833785df5e75e2c8bc34045a55a6
Run...
$ python3 ml.py
Matplotlib created a temporary config/cache directory at /tmp/matplotlib-rk288ipf because the default path (/home/ml/.config/matplotlib) is not a writable directory; it is highly recommended to set the MPLCONFIGDIR environment variable to a writable directory, in particular to speed up the import of Matplotlib and to better support multiprocessing.
Matplotlib is building the font cache; this may take a moment.
qt.qpa.xcb: X server does not support XInput 2
failed to get the current screen resources
Well, update OpenGL and x11-apps, rerun
$ python3 ml.py
Matplotlib created a temporary config/cache directory at /tmp/matplotlib-87at6bw8 because the default path (/home/zzx/.config/matplotlib) is not a writable directory; it is highly recommended to set the MPLCONFIGDIR environment variable to a writable directory, in particular to speed up the import of Matplotlib and to better support multiprocessing.
qt.qpa.xcb: X server does not support XInput 2
failed to get the current screen resources
Seems we can not get the out_file.png
, but...
$ export QT_DEBUG_PLUGINS=1
And rerun the file, we get the image, :)
Upvotes: 2
Reputation: 925
I was facing it on Colab, and the following code lines solved it. Put it at the beginning of the notebook. Reference
### CREATE VIRTUAL DISPLAY ###
!apt-get install -y xvfb # Install X Virtual Frame Buffer
import os
os.system('Xvfb :1 -screen 0 1600x1200x16 &') # create virtual display with size 1600x1200 and 16 bit color. Color can be changed to 24 or 8
os.environ['DISPLAY']=':1.0' # tell X clients to use our virtual DISPLAY :1.0.
%matplotlib inline
### INSTALL GHOSTSCRIPT (Required to display NLTK trees) ###
!apt install ghostscript python3-tk
Upvotes: 11
Reputation: 1665
I want to add an answer here that noone has explicitly stated with implementation.
This is a great resource to refer to for this failure: https://matplotlib.org/faq/usage_faq.html
In my case, using matplotlib.use
did not work because it was somehow already set somewhere else. However, I was able to get beyond the error by defining an environment variable:
export MPLBACKEND=Agg
This takes care of the issue.
My error was in a CircleCI flow specifically, and this resolved the failing tests. One wierd thing was, my tests would pass when run using pytest
, however would fail when using parallelism
along with circleci tests split
feature. However, declaring this env variable resolved the issue.
Upvotes: 3
Reputation: 7952
In order to see images, plots and anything displayed on windows on your remote machine you need to connect to it like this:
ssh -X user@hostname
That way you enable the access to the X server. The X server is a program in the X Window System that runs on local machines (i.e., the computers used directly by users) and handles all access to the graphics cards, display screens and input devices (typically a keyboard and mouse) on those computers.
More info here.
Upvotes: 5
Reputation: 7059
To add up on the answer, I used this at the beginning of the needed script. So it runs smoothly on different environments.
import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
print('no display found. Using non-interactive Agg backend')
mpl.use('Agg')
import matplotlib.pyplot as plt
Because I didn't want it to be alsways using the 'Agg'
backend, only when it would go through Travis CI for example.
Upvotes: 65
Reputation: 36635
Matplotlib chooses Xwindows backend by default. You need to set matplotlib to not use the Xwindows backend.
Add this code to the start of your script (before importing pyplot) and try again:
import matplotlib
matplotlib.use('Agg')
Or add to .config/matplotlib/matplotlibrc
line backend: Agg
to use non-interactive backend.
echo "backend: Agg" > ~/.config/matplotlib/matplotlibrc
Or when connect to server use ssh -X remoteMachine
command to use Xwindows.
Also you may try to export display: export DISPLAY=mymachine.com:0.0
.
For more info: https://matplotlib.org/faq/howto_faq.html#matplotlib-in-a-web-application-server
Upvotes: 348
Reputation: 121
Another solution is to install Xvfb, and export your display to it. ie:
disp=:8
screen=0
geom=640x480x24
exec Xvfb $disp -screen $screen $geom 2>/tmp/Xvfb.log &
Then
$ export DISPLAY=:8
$ ./example.py
Upvotes: 9
Reputation: 937
You can solve it by adding these two lines in the VERY beginning of your .py script.
import matplotlib
matplotlib.use('Agg')
PS: The error will still exists if these two lines are not added in the very beginning of the source code.
Upvotes: 91
Reputation: 51
I also met this problem while using Xshell to connect Linux server.
After seaching for methods, I find Xming + Xshell to solve image imshow problem with matplotlib.
If solutions aboved can't solve your problem, just try to download Xming under the condition you're using Xshell. Then set the attribute in Xshell, SSH->tunnel->X11transfer->choose X DISPLAY localhost:0.0
Upvotes: 4
Reputation: 479
I had this same issue trying to run a simple tkinter app remotely on a Raspberry Pi. In my case I did want to display the tkinter GUI on the pi display, but I want to be able to execute it over SSH from my host machine. I was also not using matplotlib, so that wasn't the cause of my issue. I was able to resolve the issue by setting the DISPLAY environment variable as the error suggests with the command:
export DISPLAY=:0.0
A good explanation of what the display environment variable is doing and why the syntax is so odd can be found here: https://askubuntu.com/questions/432255/what-is-display-environment-variable
Upvotes: 22