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

3voto

Shital Shah Punkte 54846

Um sicherzustellen, dass Ihr Code auf Windows, Linux und OSX sowie auf Systemen mit und ohne Anzeige portabel ist, würde ich folgenden Code-Ausschnitt empfehlen:

import matplotlib
import os
# muss vor dem Import von matplotlib.pyplot oder pylot stehen!
if os.name == 'posix' and "DISPLAY" not in os.environ:
    matplotlib.use('Agg')

# nun andere Dinge von matplotlib importieren
import matplotlib.pyplot as plt

Kredit: https://stackoverflow.com/a/45756291/207661

1voto

Kim Miller Punkte 870

Für Google Cloud Machine Learning Engine:

import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages

Und dann zum Speichern in eine Datei:

#PDF erstellen und speichern
    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()

und um das PDF zu erstellen:

multi_page(report_name)

0voto

KSD Punkte 33
import matplotlib
matplotlib.use('Agg')

hat für mich funktioniert, solange ich die Plotting-Funktionen/den Code direkt aufgerufen habe. Aber wenn du

from joblib import Parallel, delayed

Parallel und delayed Module zum Parallelisieren deines Codes verwendest, musst du

matplotlib.rcParams.update({'backend': 'Agg'})

Zeile innerhalb deiner Funktion hinzufügen, damit das agg Backend funktioniert.

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