Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/three.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 使用matplotlib自动检测显示可用性_Python_Linux_Matplotlib - Fatal编程技术网

Python 使用matplotlib自动检测显示可用性

Python 使用matplotlib自动检测显示可用性,python,linux,matplotlib,Python,Linux,Matplotlib,我在脚本中生成matplotlib图形,可以使用图形显示或不使用图形显示交替运行。我希望脚本能够自动调整:使用display时,它应该以交互方式显示图形,而不使用display时,它应该将图形保存到文件中 从对问题的回答中,我了解到可以使用Agg后端进行非交互式绘图 因此,我尝试使用以下代码: import matplotlib try: import matplotlib.pyplot as plt fig = plt.figure() havedisplay = Tr

我在脚本中生成matplotlib图形,可以使用图形显示或不使用图形显示交替运行。我希望脚本能够自动调整:使用display时,它应该以交互方式显示图形,而不使用display时,它应该将图形保存到文件中

从对问题的回答中,我了解到可以使用Agg后端进行非交互式绘图

因此,我尝试使用以下代码:

import matplotlib
try:
    import matplotlib.pyplot as plt
    fig = plt.figure()
    havedisplay = True
except:
    matplotlib.use("Agg")
    import matplotlib.pyplot as plt
    fig = plt.figure()
    havedisplay = False
# do the plotting
if havedisplay:
    plt.show()
else:
    fig.savefig("myfig.png")
这在带有显示器的情况下除外。但是,如果没有显示,调用
matplotlib.use
无效,因为已经选择了显示。很明显,我应该调用
matplotlib。在
import matplotlib.pyplot
之前使用
,但是我不知道如何测试显示是否可用

我还尝试过使用实验函数
matplotlib.switch\u backend
而不是
matplotlib.use
,但这会产生运行时错误


是否有人知道如何使上述代码按预期工作,或者可以建议另一种方法来检测matplotlib是否有可用的显示?

使用GUI后端时,figure对象具有show()方法,您可以使用它进行切换:

import matplotlib
#matplotlib.use("Agg")

import matplotlib.pyplot as plt
fig = plt.figure()
havedisplay = False
if hasattr(fig, "show"):
    plt.show()
else:
    print "save fig"
    fig.savefig("myfig.png")

您可以直接检测python中是否有带操作系统模块的显示器。 就我而言是

>>> import os
>>> os.environ["DISPLAY"]
':0.0'
试试这个

import matplotlib,os
r = os.system('python -c "import matplotlib.pyplot as plt;plt.figure()"')
if r != 0:
    matplotlib.use('Agg')
    import matplotlib.pyplot as plt
    fig = plt.figure()
    fig.savefig('myfig.png')
else:
    import matplotlib.pyplot as plt
    fig = plt.figure()
    plt.show()

@Oz123提供的解决方案为我生成了一个语法错误。但是,我可以通过以下方式轻松检测显示器:

import os
havedisplay = "DISPLAY" in os.environ
#plotting...

无论如何,这是我能找到的最简单的方法。

结合上述两种方法,您可能会得到最好的解决方案:

havedisplay = "DISPLAY" in os.environ
if not havedisplay:
    exitval = os.system('python -c "import matplotlib.pyplot as plt; plt.figure()"')
    havedisplay = (exitval == 0)
此组合的原因是
os.system
命令的运行时间可能需要一段时间。因此,当您确定有显示时(根据
os.environ
值判断),您可以节省时间。
另一方面,即使在
os.environ
变量中未设置
DISPLAY
键,绘图方法仍有可能与图形界面配合使用(例如,在使用Windows命令行时)。

以下代码适用于我在Linux和Windows中的操作(假定有显示设备):

请注意,行
matplotlib.use('Agg')
必须出现在第一次导入
matplotlib
之后(否则将出现错误)


如果
display
不在环境中或为空字符串,则
have\u display
为False。否则,这是真的

谢谢,但是如果没有显示,我在调用
plt时已经收到一个错误。图
:“无法访问X显示,…。
havedisplay=False
不被使用。如果您取消注释使用(“Agg”)?@Oz123,当我取消注释第二行时,脚本会运行到“保存图”部分,无论是否显示,它现在显示任何内容,因为在上面的示例中没有任何内容可显示。或者你的意思是在你的代码中没有输出?谢谢,这很简单,适合我。下面是我要做的:首先
导入matplotlib
,然后检查
os.environ
是否有
键“DISPLAY”
。如果没有,请调用
matplotlib.use(“Agg”)
。然后导入matplotlib.pyplot并继续。这在windows命令行中不起作用。从cmd运行python时,
plt.show()
会打开一个带有绘图的窗口。但是,
os.environ
dict中未定义
DISPLAY
键。因此,在这种情况下,脚本将写入文件而不是打开交互式窗口。如果未定义“DISPLAY”,则此操作将失败。最好让显示=bool(os.environ.get('display',None))
。这样,如果显示未定义或为空字符串,
have\u DISPLAY
将是一个非常好的解决方案。Oz123的建议似乎更简单。我更喜欢@JindraHelcl的组合,甚至可以扩展到通过
if os.name!='保存
os.system
调用posix'和not havedisplay:
条件,由@eitanrich建议,正如我在下面提到的@Oz123的答案,这在windows命令行中使用python是不起作用的。这不适用于使用多个解释器的任何人的DISPLAY是空字符串的情况:您可能需要使用
os.system({0}-c)“将matplotlib.pyplot导入为plt;plt.figure()”'.format(sys.executable))
以选择当前解释器。因此它会检查正确的库(以防matplotlib未安装在
路径中的库上
import os
import matplotlib
if os.name == 'posix' and "DISPLAY" not in os.environ:
    matplotlib.use('Agg')
import os
have_display = bool(os.environ.get('DISPLAY', None))