当DISPLAY未定义时,使用matplotlib生成PNG

我试着用Python使用networkx。当我运行这个程序时,它得到这个错误。少了什么东西吗?

#!/usr/bin/env python


import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt


G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")




Traceback (most recent call last):
File "graph.py", line 13, in <module>
nx.draw(G)
File "/usr/lib/pymodules/python2.5/networkx/drawing/nx_pylab.py", line 124, in draw
cf=pylab.gcf()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

我现在得到一个不同的错误:

#!/usr/bin/env python


import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt


matplotlib.use('Agg')


G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.


if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
File "graph.py", line 15, in <module>
nx.draw(G)
File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
cf=pylab.gcf()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable

我现在得到一个不同的错误:

#!/usr/bin/env python


import networkx as nx
import matplotlib
import matplotlib.pyplot
import matplotlib.pyplot as plt


matplotlib.use('Agg')


G=nx.Graph()
G.add_node(1)
G.add_nodes_from([2,3,4,5,6,7,8,9,10])
#nx.draw_graphviz(G)
#nx_write_dot(G, 'node.png')
nx.draw(G)
plt.savefig("/var/www/node.png")

/usr/lib/pymodules/python2.5/matplotlib/__init__.py:835: UserWarning:  This call to matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,
or matplotlib.backends is imported for the first time.


if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
File "graph.py", line 15, in <module>
nx.draw(G)
File "/usr/lib/python2.5/site-packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py", line 124, in draw
cf=pylab.gcf()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 276, in gcf
return figure()
File "/usr/lib/pymodules/python2.5/matplotlib/pyplot.py", line 254, in figure
**kwargs)
File "/usr/lib/pymodules/python2.5/matplotlib/backends/backend_tkagg.py", line 90, in new_figure_manager
window = Tk.Tk()
File "/usr/lib/python2.5/lib-tk/Tkinter.py", line 1650, in __init__
self.tk = _tkinter.create(screenName, baseName, className, interactive, wantobjects, useTk, sync, use)
_tkinter.TclError: no display name and no $DISPLAY environment variable
181014 次浏览

你使用的是什么系统?看起来您有一个使用X11的系统,但是没有正确设置DISPLAY环境变量。尝试执行以下命令,然后重新运行您的程序:

export DISPLAY=localhost:0

主要问题是(在您的系统上)matplotlib默认选择使用x的后端。我的一台服务器也遇到了同样的问题。对我来说,解决方案是在一个读取之前任何其他pylab/matplotlib/pyplot导入的地方添加以下代码:

import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')

另一种方法是在.matplotlibrc中设置它

当登录到服务器执行代码时 用

代替
ssh -X username@servername
-X将消除无显示名称和无$ display环境变量 误差< / p >

:)

另一件需要检查的事情是当前用户是否被授权连接到X显示器。在我的例子中,root不允许这样做,matplotlib也报错了。

user@debian:~$ xauth list
debian/unix:10  MIT-MAGIC-COOKIE-1  ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xauth add debian/unix:10  MIT-MAGIC-COOKIE-1 ae921efd0026c6fc9d62a8963acdcca0
root@debian:~# xterm

来源:http://www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su

作为Reinout答案的补充。

解决这类问题的永久方法是编辑.matplotlibrc文件。通过

>>> import matplotlib
>>> matplotlib.matplotlib_fname() # This is the file location in Ubuntu '/etc/matplotlibrc'

然后将该文件中的后端修改为backend : Agg。就是这样。

我只是重复@Ivo Bosticky说过的话,这可以被忽略。将这些行放在py文件的非常开头。

import matplotlib
matplotlib.use('Agg')

或者一个会得到错误

*/usr/lib/pymodules/python2.7/matplotlib/__init__.py:923: UserWarning:  This call to   matplotlib.use() has no effect
because the the backend has already been chosen;
matplotlib.use() must be called *before* pylab, matplotlib.pyplot,*

这将解决所有显示问题

简单的答案是花一点时间正确地准备执行环境。

准备执行环境的第一个技巧是使用matplotlibrc文件,正如克里斯Q的明智建议。,设置

backend : Agg

在那个文件里。你甚至可以控制——不需要修改代码——matplotlib如何查找并找到matplotlibrc文件

准备执行环境的第二个技巧是使用MPLBACKEND环境变量(并通知你的用户使用它):

export MPLBACKEND="agg"
python <program_using_matplotlib.py>

这很方便,因为您甚至不需要在磁盘上提供另一个文件就可以使其工作。例如,我在持续集成测试中使用了这种方法,并在没有显示的远程机器上运行。

在Python代码中将matplotlib后端硬编码为“Agg”,就像用大锤子把一个方钉子敲进一个圆洞,相反,你可以告诉matplotlib它需要是一个方洞。

我发现这个代码段在X和no-X环境之间切换时工作得很好。

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

我在通过Spark使用matplotlib时得到了错误。matplotlib.use('Agg')不适合我。最后,下面的代码为我工作。更多在这里

import matplotlib.pyplot as plt.
plt.switch_backend('agg')

谷歌云机器学习引擎:

import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages

然后打印到文件:

#PDF build and save
def multi_page(filename, figs=None, dpi=200):
pp = PdfPages(filename)
if figs is None:
figs = [mpl.pyplot.figure(n) for n in mpl.pyplot.get_fignums()]
for fig in figs:
fig.savefig(pp, format='pdf', bbox_inches='tight', fig_size=(10, 8))
pp.close()

并创建PDF:

multi_page(report_name)
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

这对我很管用。

为了确保你的代码在Windows, Linux和OSX以及有和没有显示的系统上都是可移植的,我建议以下代码片段:

import matplotlib
import os
# must be before importing matplotlib.pyplot or pylab!
if os.name == 'posix' and "DISPLAY" not in os.environ:
matplotlib.use('Agg')


# now import other things from matplotlib
import matplotlib.pyplot as plt

信贷:https://stackoverflow.com/a/45756291/207661

import matplotlib
matplotlib.use('Agg')

只要我直接调用绘图函数/代码,就可以工作。但如果你在使用

from joblib import Parallel, delayed

Paralleldelayed模块用于并行你的代码,然后你需要添加

matplotlib.rcParams.update({'backend': 'Agg'})

agg后端工作。