Générer un PNG avec matplotlib lorsque L'affichage n'est pas défini
j'essaie d'utiliser networkx avec Python. Quand j'exécute ce programme il obtient cette erreur. Est-il quelque chose qui manque?
#!/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
j'ai une autre erreur:
#!/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
j'ai une autre erreur:
#!/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
11 réponses
le problème principal est que (sur votre système) matplotlib choisit un backend x-using par défaut. J'ai juste eu le même problème sur un de mes serveurs. La solution pour moi était d'ajouter le code suivant dans un endroit qui obtient lu avant tout autre pylab / matplotlib / pyplot importation:
import matplotlib
# Force matplotlib to not use any Xwindows backend.
matplotlib.use('Agg')
L'alternative est de le mettre dans votre .matplotlibrc 151960920"
en complément de la réponse de Reinout.
la façon permanente de résoudre ce genre de problème est d'éditer .fichier matplotlibrc. Trouver via
>>> import matplotlib
>>> matplotlib.matplotlib_fname()
# This is the file location in Ubuntu
'/etc/matplotlibrc'
puis modifier le backend dans ce fichier en backend : Agg
. Qui est-il.
la réponse claire est de prendre un peu de temps pour préparer correctement votre environnement d'exécution.
la première technique que vous avez pour préparer votre environnement d'exécution est d'utiliser un matplotlibrc
fichier, comme sagement recommandé par Chris Q. , paramètre
backend : Agg
dans ce dossier. Vous pouvez même contrôler - sans modification de code - comment et où matplotlib cherche et trouve matplotlibrc
fichier .
la seconde technique que vous avez à préparer votre environnement d'exécution est d'utiliser la variable d'environnement "1519160920 MPLBACKEND
(et d'informer vos utilisateurs de l'utiliser):
export MPLBACKEND="agg"
python <program_using_matplotlib.py>
C'est pratique parce que vous n'avez même pas à fournir un autre fichier sur le disque pour faire ce travail. J'ai utilisé cette approche, par exemple, en testant l'intégration continue et en tournant sur des machines distantes qui n'ont pas de afficher.
coder dur votre backend matplotlib en " Agg " dans votre code Python, c'est comme frapper une cheville carrée dans un trou rond avec un gros marteau, alors que, à la place, vous auriez pu juste dire à matplotlib qu'il a besoin d'être un trou Carré.
je vais juste répéter ce que @Ivo Bosticky a dit qui peut être négligé. Mettez ces lignes au très début du fichier py.
import matplotlib
matplotlib.use('Agg')
Ou l'on pourrait obtenir d'erreur
*/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,*
Cela permettra de résoudre tous les problème d'Affichage
j'ai eu l'erreur en utilisant matplotlib à travers Spark. matplotlib.use('Agg')
ne marche pas pour moi. En fin de compte, le code suivant fonctionne pour moi. Plus ici
import matplotlib.pyplot as plt.
plt.switch_backend('agg')
lors de la signature sur le serveur pour exécuter le code utilisez ceci à la place:
ssh -X username@servername
le -X
supprimera la variable d'environnement no display name et no $DISPLAY
erreur
:)
j'ai trouvé que cet extrait fonctionne bien quand on passe d'un environnement X à un environnement no-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
quel système utilisez-vous? Il semble que vous ayez un système avec X11, mais la variable D'environnement D'affichage n'était pas correctement définie. Essayez d'exécuter la commande suivante, puis relancez votre programme:
export DISPLAY=localhost:0
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
ça me va.
Une autre chose à vérifier est de savoir si votre utilisateur est autorisé à se connecter à l'écran X. Dans mon cas, root n'a pas été autorisé à faire cela et matplotlib se plaignait avec la même erreur.
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
source: http://www.debian-administration.org/articles/494 https://debian-administration.org/article/494/Getting_X11_forwarding_through_ssh_working_after_running_su
Pour Google Cloud Machine Learning Engine:
import matplotlib as mpl
mpl.use('Agg')
from matplotlib.backends.backend_pdf import PdfPages
et ensuite imprimer dans le fichier:
#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()
et pour créer le PDF:
multi_page(report_name)