_tkinter.TclError: no display name and no $DISPLAY environment variable

Question:

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?

Asked By: Po-Yu Kao

||

Answers:

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

Answered By: Serenity

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

Answered By: ajgriese

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.

Answered By: Qihui

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

Answered By: Mode

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

Answered By: Joseph

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.

Answered By: Sylhare

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.

Answered By: tsveti_iko

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.

Answered By: rrlamichhane

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
Answered By: Vishal Gupta

Try to use python 3, every problem are solved

Answered By: Noah Drisort

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, 🙂
out_file.png

Answered By: LinconFive
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.