336 Stimmen

Generierung einer PNG mit matplotlib, wenn DISPLAY nicht definiert ist

Ich versuche, networkx mit Python zu verwenden. Wenn ich dieses Programm ausführe, erhalte ich diesen Fehler. Fehlt etwas?

#!/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 
    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

Jetzt erhalte ich einen anderen Fehler:

#!/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:  Dieser Aufruf von matplotlib.use() hat keine Auswirkung,
weil das Backend bereits ausgewählt wurde;
matplotlib.use() muss *vor* pylab, matplotlib.pyplot
oder matplotlib.backends importiert werden, bevor es zum ersten Mal verwendet wird.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in 
    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

Jetzt erhalte ich einen anderen Fehler:

#!/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:  Dieser Aufruf von matplotlib.use() hat keine Auswirkung,
weil das Backend bereits ausgewählt wurde;
matplotlib.use() muss *vor* pylab, matplotlib.pyplot
oder matplotlib.backends importiert werden, bevor es zum ersten Mal verwendet wird.

  if warn: warnings.warn(_use_error_msg)
Traceback (most recent call last):
  File "graph.py", line 15, in 
    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

3 Stimmen

9 Stimmen

Verschieben Sie den Aufruf von matplotlib.use('Agg') über Ihre anderen Imports, insbesondere sollte er vor dem Import von matplotlib.pyplot stehen.

0 Stimmen

@IvoBosticky Kommentar hat es auch für mich gelöst: Das einzige, was irreführend ist, ist "über Ihren anderen Imports". Es sollte offensichtlich sein, dass Sie matplotlib importieren müssen, bevor... Dies ist die gesamte Einstellung, die für mich funktioniert hat:
importiere matplotlib // matplotlib.use('Agg') // importiere matplotlib.pyplot as plt

17voto

Matthias123 Punkte 842

Ich fand dieses Snippet gut zu funktionieren, wenn man zwischen X- und Nicht-X-Umgebungen wechselt.

import os
import matplotlib as mpl
if os.environ.get('DISPLAY','') == '':
    print('Kein Display gefunden. Verwende nicht-interaktives Agg-Backend')
    mpl.use('Agg')
import matplotlib.pyplot as plt

0 Stimmen

In meiner Meinung ist dies eine überlegene Lösung als die akzeptierte, obwohl sie die Frage nicht direkt beantwortet und eine Frage beantwortet, die nicht gestellt wurde.

14voto

Beim Anmelden auf dem Server, um den Code auszuführen, verwenden Sie stattdessen:

ssh -X benutzername@servername
das -X wird den Fehler "Kein Anzeigename und keine $DISPLAY-Umgebungsvariable" beseitigen

)

1 Stimmen

Ich muss '-X' verwenden, um das .png-Bild speichern zu können. Vielen Dank.

0 Stimmen

Dies wird fehlschlagen, wenn ein langer Prozess bei einem SSH-Timeout abbricht oder wenn Sie aus irgendeinem Grund die Verbindung trennen müssen. Beachten Sie, dass auch ein Timeout auftreten kann, wenn der verbindende Client in den Ruhezustand geht.

0 Stimmen

Sie können Timeouts verhindern, indem Sie -o ServerAliveCountMax=120 -o ServerAliveInterval=30 hinzufügen, was den SSH-Client alle 30 Sekunden ein leeres Paket senden lässt, maximal 1 Stunde.

6voto

Qing En Punkte 61
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt

Es funktioniert für mich.

5voto

Michael Aaron Safyan Punkte 90663

Auf welchem System sind Sie? Es sieht so aus, als ob Sie ein System mit X11 haben, aber die DISPLAY-Umgebungsvariable wurde nicht korrekt gesetzt. Versuchen Sie, den folgenden Befehl auszuführen und führen Sie dann Ihr Programm erneut aus:

export DISPLAY=localhost:0

0 Stimmen

Aber warum muss es eine Anzeigegröße setzen, ich bin remote auf diesem Server angemeldet, alles, was es tun sollte, ist eine PNG-Datei zu generieren???

1 Stimmen

@krisdigitx, wenn Sie remote verbunden sind, setzen Sie keine Anzeigenvariable; verwenden Sie stattdessen das "-XY" Flag, wenn Sie sich verbinden. Um anzuzeigen, muss es wissen, an welchen Xserver das Bild gesendet werden soll; in diesem Fall wäre es die Anzeige Ihres Computers statt des Remote-Computers. Durch Verwendung des "-XY" Flags setzt SSH automatisch die DISPLAY-Variable so, dass sie auf die Anzeige des verbindenden Computers zeigt.

0 Stimmen

@krisdigitx, Ich stimme zu, es ist sehr seltsam, dass es das tut; Meine Vermutung ist jedoch, dass es das Bild mit X11 malt und dann das Ergebnis mit X11 speichert.

3voto

Alex Punkte 859

Eine weitere Sache, die Sie überprüfen sollten, ist, ob Ihr aktueller Benutzer berechtigt ist, eine Verbindung zum X-Display herzustellen. In meinem Fall durfte root das nicht tun und matplotlib hat mit demselben Fehler reklamiert.

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

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

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X