Generieren eines PNG mit Matplotlib, wenn DISPLAY nicht definiert ist

Lesezeit: 8 Minuten

Benutzer-Avatar
krisdigitx

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

Ich bekomme jetzt 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:  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

Ich bekomme jetzt 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:  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

  • mögliches Duplikat von Generieren von Matplotlib-Graphen ohne laufenden X-Server

    – Jouni K. Seppänen

    21. Februar 2011 um 21:26 Uhr

  • Verschieben Sie den Aufruf zu matplotlib.use(‘Agg’) über Ihre anderen Importe, insbesondere sollte er vor dem Import von matplotlib.pyplot erfolgen

    – Ivo Bosticky

    25. Juni 2011 um 1:18 Uhr

  • Der Kommentar von @IvoBosticky hat es auch für mich gelöst: Das einzige, was irreführend ist, ist “über Ihren anderen Importen”. Es sollte offensichtlich sein, dass Sie zuvor matplotlib importieren müssen … Dies ist die gesamte Einstellung, die für mich funktioniert hat: import matplotlib // matplotlib.use(‘Agg’) // import matplotlib.pyplot as plt

    – mrk

    20. Juni 2017 um 7:52 Uhr


Benutzer-Avatar
Reinout van Rees

Das Hauptproblem ist, dass matplotlib (auf Ihrem System) standardmäßig ein x-verwendendes Backend auswählt. Ich hatte gerade das gleiche Problem auf einem meiner Server. Die Lösung für mich war, den folgenden Code an einer Stelle hinzuzufügen, die gelesen wird Vor jedes andere pylab/matplotlib/Pyplot importieren:

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

Die Alternative besteht darin, es in Ihrer .matplotlibrc festzulegen

  • Wichtiger Hinweis: .use muss aufgerufen werden, bevor pyplot importiert wird. Wenn Sie beispielsweise nur versuchen, pyplot zu importieren, müssen Sie zuerst matplotlib importieren, use aufrufen und dann pyplot importieren.

    – Seaotternerd

    8. November 2013 um 9:15 Uhr

  • Der obige Kommentar wird durch diese Antwort näher erläutert.

    – 0 _

    28. Februar 2014 um 6:15 Uhr

  • Wie “setzen Sie es in Ihre .matplotlibrc”?

    – tommy.carstensen

    5. Juli 2015 um 20:32 Uhr

  • backend: agg in ~/.config/matplotlib'/matplotlibrc (als Beispiel siehe http://matplotlib.org/faq/troubleshooting_faq.html#locating-matplotlib-config-dir). Siehe auch matplotlib.org/users/customizing.html, die unten auf der Seite eine Beispielkonfigurationsdatei enthält. Suchen Sie auf dieser Seite nach “agg” und Sie sehen die Konfigurationsoption, die Sie benötigen.

    – Reinout van Rees

    6. Juli 2015 um 8:48 Uhr

  • Als Referenz, hier ist der Link in der Matplotlib-Dokumentation, die dies erklärt. (+1, tolle Antwort, hat mir perfekt geholfen!)

    – Tim S.

    4. Februar 2016 um 20:24 Uhr

Benutzer-Avatar
Chris.Q

Nur als Ergänzung zu Reinouts Antwort.

Der dauerhafte Weg, um diese Art von Problem zu lösen, besteht darin, die .matplotlibrc-Datei zu bearbeiten. Finde es über

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

Ändern Sie dann das Backend in dieser Datei in backend : Agg. Das ist es.

  • Profi-Tipp: einstellen $MATPLOTLIBRC zum Verzeichnis wo Sie Ihre eigene matplotlibrc hineinwerfen möchten.

    – Kenneth Hoste

    29. August 2013 um 18:19 Uhr

  • Ein bisschen übertrieben für ein Problem wie dieses, aber ich denke, wenn der Server immer kopflos arbeitet, ist es sinnvoll, eine Konfigurationsdatei zu ändern. Hätte dies Nebenwirkungen auf die Funktionsweise von Matplotlib?

    – Bruce John Jenner Lawso

    13. September 2016 um 1:45 Uhr


  • Ich verwende Matplotlib auf einem Webserver, also war dies die Antwort für mich. Ich habe keine Nebenwirkungen bemerkt.

    – Spitz

    25. November 2017 um 12:14 Uhr

Benutzer-Avatar
Gotgene

Die saubere Antwort ist, sich ein wenig Zeit zu nehmen, um Ihre Ausführungsumgebung richtig vorzubereiten.

Die erste Technik, mit der Sie Ihre Ausführungsumgebung vorbereiten müssen, ist die Verwendung von a matplotlibrc Datei, wie von Chris Q. empfohlen, Einstellung

backend : Agg

in dieser Datei. Sie können sogar steuern – ohne Codeänderungen – wie und wo matplotlib die sucht und findet matplotlibrc Datei.

Die zweite Technik, mit der Sie Ihre Ausführungsumgebung vorbereiten müssen, ist die Verwendung von MPLBACKEND Umgebungsvariable (und informieren Sie Ihre Benutzer, davon Gebrauch zu machen):

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

Dies ist praktisch, da Sie nicht einmal eine weitere Datei auf der Festplatte bereitstellen müssen, damit dies funktioniert. Ich habe diesen Ansatz zum Beispiel beim Testen in der kontinuierlichen Integration und beim Ausführen auf Remote-Computern ohne Displays verwendet.

Das Hartcodieren Ihres Matplotlib-Backends in „Agg“ in Ihrem Python-Code ist wie das Schlagen eines quadratischen Stifts in ein rundes Loch mit einem großen Hammer, obwohl Sie stattdessen matplotlib einfach sagen könnten, dass es ein quadratisches Loch sein muss.

  • Die zweite Technik sieht in dieser Situation am elegantesten aus.

    – Dmitri Kabanow

    17. Oktober 2017 um 20:22 Uhr

  • Die Verwendung von MPLBACKEND hat es für mich gelöst. Definitiv die eleganteste Art!

    – SaturnVonTitan

    18. Mai 2018 um 4:32 Uhr

Benutzer-Avatar
Benutzer3282611

Ich habe den Fehler bei der Verwendung von matplotlib über Spark erhalten. matplotlib.use('Agg') funktioniert bei mir nicht. Am Ende funktioniert der folgende Code für mich. Mehr hier

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

Benutzer-Avatar
Somum

Ich werde nur wiederholen, was @Ivo Bosticky gesagt hat, was übersehen werden kann. Setzen Sie diese Zeilen auf die SEHR Anfang der py-Datei.

import matplotlib
matplotlib.use('Agg') 

Oder man würde einen Fehler bekommen

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

Dadurch werden alle Anzeigeprobleme behoben

Benutzer-Avatar
Mathias123

Ich fand, dass dieses Snippet gut funktioniert, wenn zwischen X- und No-X-Umgebungen gewechselt wird.

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

Benutzer-Avatar
DaveShaw

Wenn Sie sich beim Server anmelden, um den Code auszuführen, verwenden Sie stattdessen Folgendes:

ssh -X username@servername

das -X wird den Fehler „kein Anzeigename“ und „keine $DISPLAY-Umgebungsvariable“ beseitigen

🙂

  • Ich muss ‘-X’ verwenden, um das .png-Bild zu speichern. Danke vielmals.

    – Nr

    12. März 2012 um 22:02 Uhr


  • Dies wird für einen langen Prozess fehlschlagen, wenn ssh abläuft oder wenn Sie aus irgendeinem Grund die Verbindung trennen müssen. Beachten Sie, dass es sogar zu einer Zeitüberschreitung kommen kann, wenn der verbindende Client in den Ruhezustand wechselt.

    – posdef

    13. Dezember 2016 um 16:00 Uhr

  • Sie können Zeitüberschreitungen verhindern, indem Sie hinzufügen -o ServerAliveCountMax=120 -o ServerAliveInterval=30 Dadurch sendet der SSH-Client alle 30 Sekunden für maximal 1 Stunde ein leeres Paket.

    – Alex

    15. Juli 2019 um 15:42 Uhr


1086210cookie-checkGenerieren eines PNG mit Matplotlib, wenn DISPLAY nicht definiert ist

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy