【问题标题】:How to build a Python REPL with non-blocking matplotlib (like IPython's %matplotlib) on macOS如何在 macOS 上使用非阻塞 matplotlib(如 IPython 的 %matplotlib)构建 Python REPL
【发布时间】:2017-02-03 08:22:27
【问题描述】:

我正在 macOS 中编写终端 REPL,并且很难复制您使用 IPython 的 %matplotlib 魔术获得的非阻塞 matplotlib 绘图行为。

考虑以下简单的 REPL(我在 macOS 10.12 上使用来自 Anaconda 的 Python 3.5):

#!/usr/bin/env pythonw

# Basic REPL (note: doesn't show output)

_globals = _locals = globals().copy()

while True:
    command = input(">>> ")
    res = exec(command, _globals, _locals)

pythonw 是使情节正确聚焦所必需的。

如果你在这个shell中运行

import matplotlib.pyplot as plt
plt.plot([1, 2])
plt.show()

它会阻塞。我试过了

import matplotlib
matplotlib.interactive(True)
import matplotlib.pyplot as plt
plt.plot([1, 2])

这不会阻塞,但出现的绘图窗口完全没有响应。我什至无法关闭它。跑步

import matplotlib.pyplot as plt
plt.plot([1, 2])
plt.show(block=False)

是一样的。

另一方面,如果你运行

%matplotlib
import matplotlib.pyplot as plt
plt.plot([1, 2])

在 IPython 5.1.0 中,它可以完美运行。 REPL 不会阻塞,我可以与情节互动。

我尝试阅读 IPython 源代码以找出我需要复制的内容,但我无法弄清楚。我什至尝试过运行IPython.core.pylabtools.activate_matplotlib("MacOSX"),但它不起作用。

【问题讨论】:

    标签: python macos matplotlib plot ipython


    【解决方案1】:

    我发现 IPython 4.2.1 实际上做错了,这让我可以将 IPython 代码库一分为二并找到答案。

    使用prompt-toolkit 的IPython 5 有一个特殊的输入钩子,它传递给prompt-toolkit 的eventloop 参数run_application。 IPython 的输入钩子在IPython.terminal.pt_inputhooks.osx 中定义。该代码对 macOS API 进行了一系列 ctypes 调用(基本上是为了获取 GUI 事件循环)。

    我不知道如何将它用于我的问题中的虚拟 REPL,但我实际上正在使用提示工具包,所以这对我来说很好。要使用它,请使用

    from IPython.terminal.pt_inputhooks.osx import inputhook
    from prompt_toolkit.shortcuts import create_eventloop
    
    # <prompt-toolkit stuff>
    ... 
    run_application(eventloop=create_eventloop(inputhook)
    

    在导入matplotlib.pyplot 之前,您仍然需要调用matplotlib.interactive(True) 以使绘图自动显示(否则您必须一直调用plt.show(),更重要的是,绘图会阻塞)。

    【讨论】:

      猜你喜欢
      • 2019-01-27
      • 2015-03-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-05-29
      • 2016-02-12
      • 1970-01-01
      相关资源
      最近更新 更多