Emacs Python-inferior shell在matplotlib show()命令后未显示提示符

11

我一直在尝试使用numpy和matplotlib,并在从emacs内置shell中运行Python时遇到了一些错误。

当我将py文件发送到shell解释器后,我可以在代码执行后运行命令。 命令提示符“ >>>”显示正常。 但是,在对绘图调用matplotlib show命令后,shell挂起,命令提示符没有显示。

>>> plt.plot(x,u_k[1,:]);
[<matplotlib.lines.Line2D object at 0x0000000004A9A358>]
>>> plt.show();

我正在使用传统的C-Python实现,在Win7上使用Fabian Gallina的Python python.el v.0.23.1在emacs 23.3下运行。

类似的问题已经在i-python平台下提出:running matplotlib or enthought.mayavi.mlab from a py-shell inside emacs on windows

更新:我在全新安装的Win 7 x64上重现了这个问题,安装了从python网站获取的典型python 2.7.2二进制文件,并且在Windows上使用numpy 1.6.1和matplotlib 1.1.0进行了测试,emacs版本为23.3和23.4。

emacs shell中一定存在某个bug。


另外,如果我在从Windows命令行启动的Python环境中运行相同的命令,则一切正常。因此,只有来自Emacs的Python劣质环境给我带来了麻烦。 - octi
你尝试过使用 ansi-termeshell 吗?我记得读过一些应用程序不喜欢 M-x shell 提供的 IO 重定向。有关概述,请参阅此备选 shell 的文章 - Devin M
我该如何在Emacs中指定Python在eshell或ansi-term中运行,而不是通过M-x shell调用的shell中运行?我没有看到教程中指定这一点的地方。 - octi
我也尝试了python-mode.el,但是出现了相同的行为。也许我的emacs劣质shell有问题? - octi
5个回答

4
我认为有两种方法可以做到这一点。
  1. Use ipython. Then you can use -pylab option. I don't use Fabian Gallina's python.el, but I guess you will need something like this:

    (setq python-shell-interpreter-args "-pylab")
    

    Please read the documentation of python.el.

  2. You can manually activate interactive mode by ion

    >>> from matplotlib import pyplot as plt
    >>> plt.ion()
    >>> plt.plot([1,2,3])
    [<matplotlib.lines.Line2D object at 0x20711d0>]
    >>>
    

1
上面的代码可以工作,但是当我尝试在命令提示符后面加上print('hello')时,它就会卡住。有人能复制我的问题吗? - octi
很奇怪...也许是没有启用,但你是否使用相同的选项启动Python?你可以在Emacs shell和Windows shell中打印sys.argv来检查它。 - tkf
关闭窗口后,print 命令还能执行吗?我的意思是,(1) 执行上述代码,(2) 执行 print("hello") 但没有任何输出,(3) 关闭 matplotlib 窗口,然后你会看到 "hello",对吗? - tkf
你说的“从Windows命令行启动”是什么意思?是启动某个程序打开Python提示符,还是打开Windows命令提示符并输入“python”,然后按回车键启动Python shell?如果是前者,可能有一些我不知道的魔法,因为我不使用Windows... - tkf
Windows 命令提示符 > 输入 python > 然后将命令发送到解释器。这里没有奇怪的行为。至于 Emacs shell,即使我关闭窗口,提示符也不会出现。此外,即使在调用 plot 后不调用 show 命令,命令提示符也会挂起/不显示。解释器是相同的,但 shell 不同。 - octi
显示剩余8条评论

2

您可以使用不同的后端:

最初的回答:

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

其他GUI后端:

  • TkAgg
  • WX
  • QTAgg
  • QT4Agg

如果您正在使用Elpy,请使用C-u C-c C-c运行您的代码。

注:Original Answer翻译成"最初的回答"

0

我认为我已经找到了一种更简单的方法来挂起劣质的shell,但仅在调用pdb时。通过提供“python”作为要运行的程序来启动pdb。

尝试这段代码:

print "> {<console>(1)<module>() }"

1
这里的目标不是让较差的shell挂起,而是阻止它挂起:P 这是你想要表达的吗? - octi

0

经过大量的时间和在matplotlib项目页面和python-mode页面上发布错误后,我发现在ipython.bat中提供console --matplotlib参数将解决matplotlib 1.3.1和ipython 1.2.0的问题。

这是我在我的iphython.bat文件中的内容:

@python.exe -i D:\devel\Python27\Scripts\ipython-script.py console --matplotlib %*


0

我认为这可能与show函数的行为有关:

matplotlib.pyplot.show(*args, **kw)

在ipython的pylab模式下运行时,显示所有图形并返回到ipython提示符。

在非交互模式下,显示所有图形并阻塞直到图形关闭;在交互模式下,除非在从非交互模式更改之前创建了图形(不建议),否则它没有任何效果。在这种情况下,它会显示图形但不会阻塞。

可以设置单个实验性关键字参数block,将其设置为True或False以覆盖上述阻止行为。

我认为你遇到了上面提到的阻塞行为,这会导致shell挂起。也许尝试使用以下方式运行函数:plt.show(block = False),看看是否产生您期望的输出。如果仍然有问题,请告诉我,我会尝试在本地复制您的设置。


所以我尝试了这些建议,但我仍然得到奇怪的行为。命令提示符会出现,直到我调用matplotlib.pyplot.plot函数。之后它就卡住了。 >>> print('hello') hello >>> plt.ion() >>> print('hello') hello >>> plt.plot(x,psi **2) [<matplotlib.lines.Line2D object at 0x0000000004B87128>] >>> print('hello') - octi
你确定在 Emacs 外部的 shell 和 Emacs 中运行相同版本的 Python,并且使用相同的 PYTHONPATH 环境变量吗?你可以通过 print sys.path 命令来检查路径。检查完路径后,也许检查一下你正在使用哪个后端会有所帮助。只需执行 print matplotlib.rcParams['backend'] 命令即可。 - tkf
我在Windows shell和emacs shell中都这样做了,使用的是相同的PYTHONPATH。在进行rcParams时,两者都返回TkAgg。这意味着什么? - octi
我想也许你正在加载不同的Python模块(当您有不同的PYTHONPATH时会发生这种情况),并使用不同的后端。如果后端不支持交互模式,则您的Python shell会挂起。 - tkf

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接