问题:_tkinter.TclError:没有显示名称并且没有$ DISPLAY环境变量
我在服务器中运行一个简单的python脚本:
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)
我尝试python example.py
在已安装matplotlib 1.5.1的服务器中使用该命令,但失败并显示以下错误:
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
这是怎么回事
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?
回答 0
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
回答 1
您可以通过在.py脚本的非常开头添加这两行来解决此问题。
import matplotlib
matplotlib.use('Agg')
PS:如果在源代码的开头没有添加这两行,则错误仍然存在。
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.
回答 2
为了加总答案,我在所需脚本的开头使用了它。因此它可以在不同的环境下平稳运行。
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
因为我不希望它总是使用'Agg'
后端,所以仅当它通过Travis CI时才如此。
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.
回答 3
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
回答 4
另一个解决方案是安装Xvfb,然后将显示导出到该文件。即:
disp=:8
screen=0
geom=640x480x24
exec Xvfb $disp -screen $screen $geom 2>/tmp/Xvfb.log &
然后
$ export DISPLAY =:8
$ ./example.py
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
回答 5
在使用Xshell连接Linux服务器时,我也遇到了这个问题。
在寻找方法之后,我找到了Xming + Xshell来解决matplotlib的图像显示问题。
如果上述解决方案不能解决您的问题,请尝试在使用Xshell的条件下下载Xming。然后在Xshell中设置属性,SSH->隧道-> X11transfer->选择X DISPLAY localhost:0.0
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
回答 6
为了查看图像,图解以及远程计算机的Windows上显示的所有内容,您需要像这样连接到它:
ssh -X user@hostname
这样,您就可以访问X服务器。X服务器是X窗口系统中的程序,可在本地计算机(即用户直接使用的计算机)上运行,并处理对这些计算机上的图形卡,显示屏和输入设备(通常是键盘和鼠标)的所有访问。
更多信息在这里。
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.