如何检查matplotlib的pylab后端是否在内联运行?
我正在修改一个用Python写的模块,这个模块可以用matplotlib绘制一些特殊的图表。
现在,这个模块只会把所有的图形保存为文件。
我想让它在使用ipython notebook的时候,可以直接在里面显示结果,而在其他情况下导入这个模块时,仍然保持默认的保存图形为文件的功能。
所以我需要找到一种方法,检查这个模块是否是在ipython notebook中被导入的,以及pylab是否在内联工作。
我该怎么检查呢?
3 个回答
我开始搜索这个问题,觉得我找到了一个解决办法。虽然不确定这个方法是否有文档说明或者是否是官方推荐的,但它可能真的有效:
get_ipython().config['IPKernelApp']['pylab'] == 'inline'
get_ipython()
这个方法似乎只有在运行 IPython 时才会被定义;它会返回当前的 IPython 会话。接着,你可以访问 config
属性,这个属性是一个字典,里面包含了 'IPKernelApp' 这个元素。后者本身也是一个字典,可能包含一个键 pylab
,这个键的值可以是字符串 'inline'
。
我没有深入测试,但我猜如果你没有以 inline 方式运行 pylab,上面的代码会返回 False。
更重要的是,如果你没有运行 notebook 或者没有选择 pylab 选项,它会抛出一个 KeyError 错误,所以你需要捕获这个错误,并将这个异常视为“没有”以 inline 方式运行 notebook。
最后,get_ipython()
可能会抛出一个 NameError
,这和上面提到的情况类似,这当然也意味着你没有在运行 IPython。
我只做了最基本的测试,但在我的 IPython notebook 中导入这个方法,然后在默认的 Python 命令行中运行,确实显示它是有效的。
如果这个方法对你有用,请告诉我们。
你可以试试这个:
try:
cfg = get_ipython().config
print('Called by IPython.')
# Caution: cfg is an IPython.config.loader.Config
if cfg['IPKernelApp']:
print('Within IPython QtConsole.')
try:
if cfg['IPKernelApp']['pylab'] == 'inline':
print('inline pylab loaded.')
else:
print('pylab loaded, but not in inline mode.')
except:
print('pylab not loaded.')
elif cfg['TerminalIPythonApp']:
try:
if cfg['TerminalIPythonApp']['pylab'] == 'inline':
print('inline pylab loaded.')
else:
print('pylab loaded, but not in inline mode.')
except:
print('pylab not loaded.')
except:
print('Not called by IPython.')
你可以用下面的代码来查看matplotlib的后端设置:
import matplotlib
matplotlib.get_backend()
如果你想特别检查一下是否可以在文档中直接显示matplotlib的图形,可以用:
mpl_is_inline = 'inline' in matplotlib.get_backend()
需要注意的是,在IPython笔记本中,无论当前使用的matplotlib后端是什么,你都可以始终直接显示图形,方法是:
display(fig)