Python 未定义显示时使用matplotlib生成PNG

Python 未定义显示时使用matplotlib生成PNG,python,matplotlib,graph,Python,Matplotlib,Graph,我正在尝试将networkx与Python结合使用。当我运行这个程序时,它得到了这个错误。少了什么吗 #!/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_gra

我正在尝试将networkx与Python结合使用。当我运行这个程序时,它得到了这个错误。少了什么吗

#!/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/lib/pymodules/python2.5/matplotlib/_init__;.py:835:UserWarning:调用matplotlib.use()无效
因为已经选择了后端;
matplotlib.use()必须在*pylab、matplotlib.pyplot、,
或matplotlib.backends首次导入。
如果警告:警告。警告(使用错误消息)
回溯(最近一次呼叫最后一次):
文件“graph.py”,第15行,在
nx.绘图(G)
文件“/usr/lib/python2.5/site packages/networkx-1.2.dev-py2.5.egg/networkx/drawing/nx_pylab.py”,绘图中的第124行
cf=pylab.gcf()
gcf中的文件“/usr/lib/pymodules/python2.5/matplotlib/pyplot.py”,第276行
返回数字()
文件“/usr/lib/pymodules/python2.5/matplotlib/pyplot.py”,图中第254行
**kwargs)
文件“/usr/lib/pymodules/python2.5/matplotlib/backends/backend\u tkagg.py”,第90行,在新的图形管理器中
window=Tk.Tk()
文件“/usr/lib/python2.5/lib tk/Tkinter.py”,第1650行,在__
self.tk=\u tkinter.create(屏幕名、基本名、类名、交互、wantobjects、useTk、同步、使用)
_tkinter.TclError:没有显示名称和$display环境变量

您使用的是什么系统?看起来您的系统带有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
将去掉no display name和no$display环境变量 错误


:)

要检查的另一件事是当前用户是否有权连接到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

资料来源:

这是对雷诺特答案的补充

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

>>> import matplotlib
>>> matplotlib.matplotlib_fname() # This is the file location in Ubuntu '/etc/matplotlibrc'
导入matplotlib
>>>>matplotlib.matplotlib_fname() #这是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,* */usr/lib/pymodules/python2.7/matplotlib/_init__u.py:923:UserWarning:调用matplotlib.use()无效 因为已经选择了后端; matplotlib.use()必须在*pylab、matplotlib.pyplot、*
这将解决所有显示问题

明确的答案是花一点时间正确准备执行环境

准备执行环境的第一项技术是使用
matplotlibrc
文件设置

在那个档案里。您甚至可以在不更改代码的情况下进行控制

准备执行环境的第二种技术是使用(并通知用户使用):

导出mplbend=“agg” python 这很方便,因为您甚至不需要在磁盘上提供另一个文件来实现这一点。例如,我在连续集成测试中采用了这种方法,并在没有显示器的远程机器上运行


在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 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)

它适合我。

为了确保您的代码可以跨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

信用证:

但是为什么它需要设置一个显示变量,我远程登录到这个服务器,它所要做的就是生成一个PNG文件???@kridigitx,如果你是远程连接的,不要设置显示变量;连接时请使用“-XY”标志。为了显示,它需要知道将图像发送到哪个Xserver;在这种情况下,它将显示您的计算机,而不是远程计算机。使用“-XY”标志会使SSH自动设置显示变量,以指向连接计算机的显示。@Kristigitx,我同意,它这样做是非常奇怪的;不过,我的猜测是,它使用X11绘制图像,然后使用X11保存结果。在运行Ubuntu 16的EC2上,使用$DISPLAY的此设置不起作用——无法连接到显示“localhost:0”可能与移动调用matplotlib.use('Agg')的重复项在其他导入项之上,尤其是在导入matplotlib之前。pyplot@IvoBosticky评论也为我解决了这个问题:唯一误导的是“高于其他进口产品”。显然,您需要在。。。这是对我有效的全部设置:导入matplotlib//matplotlib.use('Agg')//import matplotlib.pyplot,因为pltI需要使用“-X”才能保存.png图像。非常感谢。如果ssh超时,或者您需要断开连接,这将在很长一段时间内失败
export MPLBACKEND="agg"
python <program_using_matplotlib.py>
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
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()
multi_page(report_name)
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
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