Python 无头 MatplotLib / Pyplot

37 投票
3 回答
25218 浏览
提问于 2025-04-16 14:49

我正在尝试让我的数据分析和报告看起来不那么刺眼,而是更具图形化,所以我在使用matplotlib/pyplot/pylab来自动生成图表文件。这些工具工作得非常好,但当我在一个没有图形界面的服务器上运行时...

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

在这个应用中,我只使用了PyLab,但经过一番搜索后,我在导入pylab之前添加了下面的内容:

import matplotlib
matplotlib.use("Agg")

这应该是改变了后端设置,但似乎没有效果。

你们觉得我哪里做错了吗?

远程机器确实支持X转发,但因为这个应用不应该需要显示任何东西,所以我觉得通常的ssh -X方法有点多余。

示例:狡猾的欺骗

在同一台机器上运行的有效代码

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")

无效的真实代码

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')

没有其他代码会影响到pyplot。

3 个回答

15

试着先导入 matplotlib,然后再设置 Agg 后台,最后再导入 numpy:

import matplotlib
matplotlib.use("Agg")
28

你描述的内容听起来没错。你运行这个代码时会发生什么呢:

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

在我的环境中运行这个代码会得到这个结果(我把它缩小了):

在这里输入图片描述

12

原来有一个工具文件(不是我写的!)在用 pylab 做其他事情。于是我把 matplotlib 的后端选择移到了最开始的页面。

撰写回答