2011-03-31 10 views
22

Estoy tratando de hacer que mi análisis de datos e informes menos apuñalado de ojos y más gráficos con archivos de gráficos generados automáticamente, y para hacer esto he estado jugando con matplotlib/pyplot/pylab. Funciona muy bien, pero cuando trato de ejecutarlo en un servidor sin cabeza ...Python Headless MatplotLib/Pyplot

tkinter.TclError: no display name and no $DISPLAY environment variable 

Para esta aplicación sólo uso PyLab, pero después de un poco de google, he añadido el siguiente para antes de la importación pylab:

import matplotlib 
matplotlib.use("Agg") 

Que debería haber cambiado el motor, pero no tuvo ningún efecto.

¿Alguna idea de lo que estoy haciendo mal?

La máquina remota tiene capacidades de reenvío de X, pero como esta aplicación no NECESITA mostrar nada, creo que el hack usual de ssh-X es exagerado.

Ejemplos: Fiendish engaño

Ejemplo de trabajo código en la misma máquina

import matplotlib 
matplotlib.use("Agg") 
import numpy as np 
import pylab as pl 


xvals=np.arange(100) 
yvals=np.cumsum(np.random.random(100)) 
yvals[-10:]=0 
yvals=np.log(yvals) 
pl.close() 

pl.plot(xvals,yvals) 
pl.xlabel("X") 
pl.ylabel("Y") 
pl.title("Title") 

pl.savefig("testgraph.png") 

de no trabajo código real

import matplotlib 
matplotlib.use("Agg") 
import numpy as np 
import pylab as pl 
import utility as util 
import os 

... non graph stuff... 
def graph_p(self): 
    pl.close() 
    channels=range(self.p.shape[0]) 
    for line in range(self.p.shape[1]): 
     yvals=np.ma.masked_invalid(map(util.watts_to_dbmhz,self.p[:,line])) 
     pl.plot(channels,yvals) #Error says it occurs here 
    pl.xlabel("Subchannel Index") 
    pl.ylabel("Power (dbmhz)") 
    pl.title("Plot of per-tone power assignments for %d lines"%self.p.shape[1]) 
    pl.savefig(self.dest+self.scenario+'-power.png') 

Nada más toca pyplot.

+0

Es muy extraño, de hecho. ¿Puedes publicar un ejemplo mínimo (no) de trabajo? El backend 'Agg' no debería necesitar X. –

+0

¡Actualizado con un ejemplo mínimo, pero ahora no puedo descifrarlo! – Bolster

Respuesta

7

Aparece un archivo de utilidad (no el mío!) estaba tirando en pylab por algo más. Cambió la selección de backend de matplotlib a la página inicial.

+6

Esto parece hacer el truco. Importar matplotlib ** antes ** cualquier otra cosa que pueda importar pylab. – Cerin

14

Todo lo que describes suena correcto. ¿Qué pasa cuando se ejecuta este:

import matplotlib 
matplotlib.use('Agg') 
import pylab 
pylab.plot([1,2], [3,4], linestyle='-') 
pylab.savefig('foo.png') 

En mi entorno se produce esto (escalé hacia abajo):

enter image description here

+0

Ver ejemplo de trabajo construido arriba ... (Por qué funciona, no tengo ni idea) – Bolster

+0

Me alegro de que esté trabajando para ti ahora. :-) – samplebias

+0

+1 Gracias por el simple ejemplo. – Geoff

7

Intente importar matplotlib y ajuste de la Agg backend antes importar numpy:

import matplotlib 
matplotlib.use("Agg") 
+0

Sin cambios en el comportamiento. Incluso cuando mpl es lo primero importado y 'usado' – Bolster