首页 文章

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

提问于
浏览
285

我正在尝试将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/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

11 回答

  • 40

    主要问题是(在你的系统上)matplotlib默认选择x-using后端 . 我在我的一台服务器上遇到了同样的问题 . 我的解决方案是在任何其他pylab / matplotlib / pyplot import之前读取的地方添加以下代码:

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

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

  • 31

    就像Reinout的回答一样 .

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

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

    然后将该文件中的后端修改为 backend : Agg . 这就对了 .

  • 1

    干净的答案是花一点时间正确准备您的执行环境 .

    准备执行环境的第一个技术是使用 matplotlibrc 文件,as wisely recommended by Chris Q.,设置

    backend : Agg
    

    在那个文件中 . 您甚至可以控制 - 无需更改代码 - how and where matplotlib looks for and finds the matplotlibrc file .

    您必须准备执行环境的第二种技术是使用MPLBACKEND environment variable(并通知您的用户使用它):

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

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

    在你的Python代码中将matplotlib后端硬编码为“Agg”就好像用一把大锤子将方形钉子钉入一个圆孔中,相反,你可能只是告诉matplotlib它需要是一个方孔 .

  • 5

    我将重复@Ivo Bosticky所说的可以忽略的内容 . 将这些行放在py文件的 VERY 开头 .

    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,*
    

    这将解决所有显示问题

  • 11

    我通过Spark使用matplotlib时出错了 . matplotlib.use('Agg') 对我不起作用 . 最后,以下代码适用于我 . 更多here

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

    登录服务器执行代码时请改用:

    ssh -X username@servername
    

    -X 将删除无显示名称并且没有$ DISPLAY环境变量错误

    :)

  • 31

    我发现在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
    
  • 13

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

    export DISPLAY=localhost:0
    
  • 3

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

    这个对我有用 .

  • 4

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

  • 68

    对于Google Cloud Machine学习引擎:

    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)
    

相关问题