【问题标题】:Emacs Python-inferior shell not showing prompt after matplotlib show() commandEmacs Python-inferior shell 在 matplotlib show() 命令后不显示提示
【发布时间】:2012-02-01 19:17:22
【问题描述】:

所以我一直在尝试使用 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 实现。在 emacs 23.3 下,在 Win7 上使用 F* Gallina 的 Python python.el v. 0.23.1。

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

更新:我已经用 python 网站上提供的典型 python 2.7.2 二进制文件以及 emacs 23.3 和 23.4 上的 numpy 1.6.1 和 matplotlib 1.1.0 复制了新安装 Win 7 x64 的问题适用于 Windows。

emacs shell 中一定有错误。

【问题讨论】:

  • 另外,如果我在从 windows 命令 shell 开始的 python 环境中运行相同的命令,一切正常。因此,给我带来麻烦的只是比 emacs 差的 python。
  • 您是否尝试过使用ansi-termeshell 我记得读过一些应用程序不喜欢M-x shell 提供的IO 重定向。有关概述,请参阅此article on alternative shells
  • 如何在 emacs 中指定 python 在 eshell 或 ansi-term 而不是通过 M-x shell 调用的 shell 中运行?我没有看到教程指定的地方。
  • 所以我也尝试了 python-mode.el 并且发生了相同的行为。那么也许我的 emacs 劣质外壳有问题?

标签: python emacs matplotlib


【解决方案1】:

我认为有两种方法可以做到。

  1. 使用 ipython。然后你可以使用-pylab 选项。 我不使用 F* Gallina 的 python.el,但我猜你需要这样的东西:

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

    请阅读python.el的文档。

  2. 您可以通过ion手动激活交互模式

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

【讨论】:

  • 所以上面的代码可以工作,但是当我在命令提示符挂起后立即尝试执行 print('hello') 时。谁能复制我的问题?
  • 这很奇怪......也许是未发酵的,但你是否使用相同的选项启动 python?您可以通过在 emacs shell 和 windows shell 中打印 sys.argv 来检查它。
  • 关闭窗口后可以打印吗?我的意思是,(1) 执行上面的代码,(2) 执行print("hello") 但没有打印出来,(3) 关闭matplotlib 窗口,然后你会看到“hello”,对吧?
  • “从windows命令shell开始”是什么意思?您启动一些打开 python 提示符的程序,或者您打开 Windows 命令提示符并输入 python 并按回车键启动 python shell?如果前者是真的,也许有一些我不知道的魔法正在发生,因为我不使用 Windows...
  • Windows 命令提示符> 键入 python > 然后将命令发送到解释器。这里没有奇怪的行为。至于 emacs shell,即使我关闭窗口,也不会出现提示。此外,即使我在调用 plot 后不调用 show 命令,命令提示符 hangs/ 也不会出现。口译员是一样的。贝壳不同。
【解决方案2】:

你可以使用不同的后端:

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

其他 GUI 后端:

  • TkAgg
  • WX
  • QTAgg
  • QT4Agg

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

【讨论】:

    【解决方案3】:

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

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

    在 ipython 及其 pylab 模式下运行时,显示所有图形和 返回 ipython 提示符。

    在非交互模式下,显示所有图形并阻塞,直到 数字已关闭;在交互模式下它没有效果,除非 数字是在从非交互式更改为之前创建的 交互模式(不推荐)。在这种情况下,它会显示 数字但不阻挡。

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

    我认为您遇到上述阻塞行为会导致 shell 挂起。也许尝试将函数运行为:plt.show(block = False) 并查看它是否产生您期望的输出。如果这仍然给您带来麻烦,请告诉我,我会尝试在本地重现您的设置。

    【讨论】:

    • 所以我尝试了这些建议,但我仍然遇到奇怪的行为。所以命令提示符会重新出现,直到我调用 matplotlib.pyplot.plot 函数。之后它就挂了&gt;&gt;&gt; print('hello')hello&gt;&gt;&gt; plt.ion()&gt;&gt;&gt; print('hello')hello&gt;&gt;&gt; plt.plot(x,psi **2)[&lt;matplotlib.lines.Line2D object at 0x0000000004B87128&gt;]&gt;&gt;&gt; print('hello')
    • 你确定你在 Emacs 之外的 shell 和 Emacs 中运行相同版本的 python 和相同的 PYTHONPATH 环境变量吗?您可以通过print sys.path查看路径。检查后,也许检查您使用的后端有帮助。只需print matplotlib.rcParams['backend']
    • 我在 Windows shell 和 emacs shell 中都这样做了,并且使用了相同的 PYTHONPATH。执行 rcParams 都返回 TkAgg。这意味着什么?
    • 我想也许你正在加载不同的 python 模块(当你有不同的 PYTHONPATH 时会发生这种情况)并使用不同的后端。如果后端不支持交互模式,你的 python shell 就会挂起。
    【解决方案4】:

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

    试试这个代码:

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

    【讨论】:

    • 这里的目标是不挂起劣质外壳,而是真正阻止它挂起:P 这就是你的意思吗?
    【解决方案5】:

    经过大量时间并在 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 控制台 --matplotlib %*

    【讨论】: