Een PNG genereren met matplotlib wanneer DISPLAY niet gedefinieerd is

Ik probeer networkx te gebruiken met Python. Als ik dit programma start, krijg ik deze foutmelding. Ontbreekt er iets?

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

Ik krijg nu een andere foutmelding:

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

Ik krijg nu een andere foutmelding:

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

Antwoord 1, autoriteit 100%

Het grootste probleem is dat (op uw systeem) matplotlib standaard een x-gebruikende backend kiest. Ik had net hetzelfde probleem op een van mijn servers. De oplossing voor mij was om de volgende code toe te voegen op een plaats die vóórelke andere import van pylab/matplotlib/pyplotwordt gelezen:

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

Het alternatief is om het in je .matplotlibrc in te stellen


Antwoord 2, autoriteit 14%

Als aanvulling op het antwoord van Reinout.

De permanente manier om dit soort problemen op te lossen, is door het .matplotlibrc-bestand te bewerken. Vind het via

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

Wijzig vervolgens de backend in dat bestand in backend : Agg. Dat is het.


Antwoord 3, autoriteit 9%

Het schone antwoord is om wat tijd te nemen om uw uitvoeringsomgeving correct voor te bereiden.

De eerste techniek die u nodig hebt om uw uitvoeringsomgeving voor te bereiden, is door een matplotlibrc-bestand te gebruiken, zoals wijselijk aanbevolen door Chris Q., instelling

backend : Agg

in dat bestand. U kunt zelfs – zonder codewijzigingen – hoe en waar matplotlib de matplotlibrcbestand.

De tweede techniek die u nodig hebt om uw uitvoeringsomgeving voor te bereiden, is het gebruik van de MPLBACKENDomgevingsvariabele(en informeer uw gebruikers om er gebruik van te maken):

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

Dit is handig omdat je niet eens een ander bestand op schijf hoeft aan te leveren om dit te laten werken. Ik heb deze aanpak toegepast bij bijvoorbeeld testen in continue integratie en draaien op externe machines zonder beeldscherm.

Het hard coderen van je matplotlib-backend naar “Agg” in je Python-code is als het slaan van een vierkante pin in een rond gat met een grote hamer, terwijl je in plaats daarvan net tegen matplotlib had kunnen zeggen dat het een vierkant gat moet zijn.


Antwoord 4, autoriteit 8%

Ik kreeg de fout tijdens het gebruik van matplotlib via Spark. matplotlib.use('Agg')werkt niet voor mij. Uiteindelijk werkt de volgende code voor mij. Meer hier

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

Antwoord 5, autoriteit 6%

Ik zal gewoon herhalen wat @Ivo Bosticky zei, wat over het hoofd kan worden gezien. Zet deze regels aan het VERYbegin van het py-bestand.

import matplotlib
matplotlib.use('Agg') 

Of je krijgt een foutmelding

*/usr/lib/pymodules/python2.7/matplotlib/__init__.py:923: UserWarning: deze aanroep naar matplotlib.use() heeft geen effect
omdat de backend al is gekozen;
matplotlib.use() moet *before* pylab, matplotlib.pyplot,* worden genoemd

Hiermee worden alle weergaveproblemen opgelost


Antwoord 6, autoriteit 3%

Ik merkte dat dit fragment goed werkte bij het schakelen tussen X- en no-X-omgevingen.

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

Antwoord 7, autoriteit 3%

Wanneer u zich aanmeldt bij de server om de code uit te voeren
gebruik in plaats daarvan dit:

ssh -X username@servername

de -Xzal de geen weergavenaam en geen $DISPLAY omgevingsvariabele verwijderen
fout

🙂


Antwoord 8

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

Het werkt voor mij.


Antwoord 9

Op welk systeem zit je? Het lijkt erop dat je een systeem hebt met X11, maar de omgevingsvariabele DISPLAY is niet correct ingesteld. Probeer de volgende opdracht uit te voeren en start uw programma opnieuw:

export DISPLAY=localhost:0

Antwoord 10

Een ander ding om te controleren is of uw huidige gebruiker geautoriseerd is om verbinding te maken met het X-display. In mijn geval mocht root dat niet doen en matplotlib klaagde met dezelfde fout.

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

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


Antwoord 11

Om ervoor te zorgen dat uw code overdraagbaar is in Windows, Linux en OSX en voor systemen met en zonder beeldschermen, raad ik u het volgende fragment aan:

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

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


Antwoord 12

Voor Google Cloud Machine Learning Engine:

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

En dan afdrukken naar bestand:

#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()

en om de PDF te maken:

multi_page(report_name)

Other episodes