web-dev-qa-db-ja.com

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
299
krisdigitx

主な問題は、(あなたのシステムの)matplotlibがデフォルトでx-usingバックエンドを選択することです。私は自分のサーバーの1つで同じ問題を抱えていました。私にとっての解決策は、beforeその他のpylab/matplotlib/pyplot importのような場所に、次のコードを追加することでした。

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

別の方法はあなたの.matplotlibrcにそれを設定することです。

502

Reinoutの答えを補完するものとして。

この種の問題を解決する恒久的な方法は、.matplotlibrcファイルを編集することです。でそれを見つける

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

それからそのファイルのバックエンドをbackend : Aggに変更します。それだ。

70
Chris.Q

明確な答えは、少し時間をかけて実行環境を正しく準備することです。

実行環境を準備するために最初に必要なテクニックは、matplotlibrcファイルを使用することです。 Chris Qが賢明に推奨しているように 、設定

backend : Agg

そのファイルに。 - コードを変更することなく - matplotlibがmatplotlibrcファイルを検索して検索する方法と場所 を制御することもできます。

実行環境を準備するために必要な2番目の方法は、 MPLBACKEND環境変数 を使用することです(そしてそれを使用するようにユーザーに通知します)。

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

これを機能させるためにディスク上に別のファイルを用意する必要すらないので、これは便利です。私はこのアプローチを採用しています。たとえば、継続的インテグレーションのテストや、ディスプレイのないリモートマシンでの実行などです。

Pythonコードでmatplotlibのバックエンドを "Agg"にハードコーディングすることは、大きな穴をあけて四角いペグを丸い穴にぶつけることに似ています。

42
gotgenes

Sparkでmatplotlibを使用しているときにエラーが発生しました。 matplotlib.use('Agg')は私にとってはうまくいきません。最後に、次のコードが私のために働きます。もっと ここ

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

@ Ivo Bostickyが言ったことを見過ごすことができるということを繰り返します。これらの行をpyファイルのVERYの先頭に置きます。

import matplotlib
matplotlib.use('Agg') 

または1つはエラーになるでしょう

 */usr/lib/pymodules/python2.7/matplotlib/__ init__.py:923:UserWarning:このmatplotlib.use()の呼び出しは効果がありません
バックエンドは既に有効になっている[; ____。] matplotlib.use()は* pylab、matplotlib.pyplot、* 
の前に*呼び出す必要があります。

これですべての表示問題が解決します

31
Somum

コードを実行するためにサーバーにサインインするときは、代わりにこれを使用してください。

ssh -X username@servername

-Xはno display nameとno $ DISPLAY環境変数エラーを取り除きます

:)

14

私は、Xと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
12
Matthias123

あなたはどんなシステムを使っていますか? X11のシステムを使用しているように見えますが、DISPLAY環境変数が正しく設定されていません。次のコマンドを実行してからプログラムを再実行してください。

export DISPLAY=localhost:0

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

わたしにはできる。

4
Qing En

もう1つ確認することは、現在のユーザーが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_s

3
Alex

あなたのコードがウィンドウズ、リナックスそして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

2
Shital Shah

Google Cloud Machine Learning Engineの場合

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)
1
Kim Miller