Generando un PNG con matplotlib cuando DISPLAY no está definido

Estoy tratando de usar networkx con Python. Cuando ejecuto este progtwig me sale este error. ¿Hay algo que falta?

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

Me sale un error diferente ahora:

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

Me sale un error diferente ahora:

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

El problema principal es que (en su sistema) matplotlib elige un backend que usa x de forma predeterminada. Acabo de tener el mismo problema en uno de mis servidores. La solución para mí fue agregar el siguiente código en un lugar que se lea antes de cualquier otra importación pylab / matplotlib / pyplot :

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

La alternativa es configurarlo en su .matplotlibrc

Solo como complemento de la respuesta de Reinout.

La forma permanente de resolver este tipo de problema es editar el archivo .matplotlibrc. Encontrarlo a través de

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

Luego modifique el backend en ese archivo al backend : Agg . Eso es.

La respuesta limpia es tomarse un poco de tiempo para preparar correctamente su entorno de ejecución.

La primera técnica que tiene para preparar su entorno de ejecución es usar un archivo matplotlibrc , tal como lo recomienda sabiamente Chris Q. ,

 backend : Agg 

en ese archivo. Incluso puede controlar, sin cambios de código, cómo y dónde busca matplotlib y encuentra el archivo matplotlibrc .

La segunda técnica que tiene para preparar su entorno de ejecución es usar la variable de entorno MPLBACKEND (e informar a sus usuarios para que la utilicen):

 export MPLBACKEND="agg" python  

Esto es útil porque ni siquiera tiene que proporcionar otro archivo en el disco para que esto funcione. He empleado este enfoque con, por ejemplo, pruebas en integración continua y ejecución en máquinas remotas que no tienen pantallas.

Codificar de forma rígida su backend matplotlib para “Agg” en su código Python es como golpear una clavija cuadrada en un agujero redondo con un martillo grande, cuando, en cambio, podría haberle dicho a matplotlib que debe ser un agujero cuadrado.

Recibí el error al usar matplotlib a través de Spark. matplotlib.use('Agg') no funciona para mí. Al final, el siguiente código funciona para mí. Más aquí

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

Solo repetiré lo que @Ivo Bosticky dijo que puede pasarse por alto. Ponga estas líneas en el inicio MUY del archivo py.

 import matplotlib matplotlib.use('Agg') 

O uno obtendria error

 * / usr / lib / pymodules / python2.7 / matplotlib / __ init__.py:923: Advertencia del usuario: esta llamada a matplotlib.use () no tiene efecto
 porque el backend ya ha sido elegido;
 matplotlib.use () debe llamarse * antes de * pylab, matplotlib.pyplot, *

Esto resolverá todos los problemas de visualización

Cuando inicie sesión en el servidor para ejecutar el código, use esto en su lugar:

 ssh -X username@servername 

el -X eliminará el nombre de no mostrar y no el error de variable de entorno $ DISPLAY

🙂

Encontré que este fragmento de código funciona bien cuando se cambia entre entornos X y 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 

¿En qué sistema estás? Parece que tienes un sistema con X11, pero la variable de entorno DISPLAY no se configuró correctamente. Intente ejecutar el siguiente comando y luego vuelva a ejecutar su progtwig:

 export DISPLAY=localhost:0 

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

Esto funciona para mi.

Otra cosa que debe verificar es si su usuario actual está autorizado para conectarse a la pantalla X. En mi caso, a la raíz no se le permitió hacer eso y matplotlib se quejaba con el mismo error.

 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 

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

Para Google Cloud Machine Learning Engine:

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

Y luego a imprimir al archivo:

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

y para crear el PDF:

 multi_page(report_name) 

Para asegurarse de que su código sea portátil en Windows, Linux y OSX y para sistemas con y sin pantallas, sugeriría el siguiente fragmento de código:

 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 

Crédito: https://stackoverflow.com/a/45756291/207661