如何在 Spyder(或任何其他调试器)的 ipdb 调试器中强制 Matplotlib 进行绘制?

Posted

技术标签:

【中文标题】如何在 Spyder(或任何其他调试器)的 ipdb 调试器中强制 Matplotlib 进行绘制?【英文标题】:How do I force Matplotlib to draw while in the ipdb debugger in Spyder (or any other debugger)? 【发布时间】:2011-10-28 04:45:05 【问题描述】:

编辑

很遗憾,目前这是不可能的。我发现它是bug in Spyder。开发者是still figuring out how to approach this。


目标

在调试代码时可视化数据(我也想使用 Spyder!)。

尝试 #1:从 Spyder 的 IPython 运行 foo.bar

使用以下代码创建一个名为 foo.py 的文件:

from ipdb import set_trace as st
import matplotlib.pyplot as plt

def bar():
    st()

在 IPython 中,键入以下内容:

In [4]: import foo

In [5]: foo.bar()
--Return--
None
> somewhere_over_the_rainbow\foo.py(5)bar()
      3 
      4 def bar():
----> 5     st()

ipdb> plt.plot([1, 2], [3, 4])
[<matplotlib.lines.Line2D object at 0x05CA8E90>]
ipdb> plt.show()

情节仍处于“冻结”状态。如果我退出调试器,绘制更新。如果我尝试关闭绘图,IPython 会崩溃。显然两者都是不可取的,也不允许我在调试时看到数据。

尝试 #2:从命令行从 IPython 运行 foo.bar

使用与尝试 #1 中相同的 foo.py:

从命令行打开 IPython:

In [4]: import foo

In [5]: foo.bar()
--Return--
None
> somewhere_over_the_rainbow\foo.py(5)bar()
      3
      4 def bar():
----> 5     st()

ipdb> plt.plot([1, 2], [3, 4])
[<matplotlib.lines.Line2D object at 0x03904070>]
ipdb> plt.show()

程序按我的预期显示情节。但我想使用 Spyder。

尝试 #3:从命令行从 IPython 运行 baz.bar

编写baz.py:

from ipdb import set_trace as st
import matplotlib.pyplot as plt

st()

从命令行打开 IPython:

In [4]: import baz
--Return--
None
> somewhere_over_the_rainbow\baz.py(4)<module>()
      2 import matplotlib.pyplot as plt
      3 
----> 4 st()

ipdb> plt.

然后 Spyder 完全冻结。

有什么建议吗?

注意 #1:在我的完整代码中,我有许多文件和许多函数,因此在一个没有函数的脚本中将它们混合在一起是不可行的。

注意 #2:使用任何 matplotlib 交互命令(例如 ion()、interactive(True) 等)均无效。

注意事项 #3:Spyder 版本 2.0.12、Python 2.6、matplotlib 1.0.1。

【问题讨论】:

C:\Python26\lib\site-packages\matplotlib\__init__.py:888: UserWarning: This call to matplotlib.use() has no effect because the the backend has already been chosen; matplotlib.use() must be called *before* pylab, matplotlib.pyplot, or matplotlib.backends is imported for the first time. if warn: warnings.warn(_use_error_msg) In [3]: matplotlib.get_backend() Out[3]: 'Qt4Agg' 你有什么版本的matplotlib? 谢谢,能够将其更改为 TkAgg。同样的问题发生了。 plt.plot() 创建了图形,但内容为白色(即里面没有写任何内容); plt.show() 什么都不做; exit() 导致 Spyder 冻结。 @eryksun 让我们continue this discussion in chat 【参考方案1】:

此处是 Spyder 维护者)Spyder 4.2.0 于 2020 年 11 月 8 日发布,支持在调试时使用交互式 Matplotlib 图的能力。开箱即用,即不需要设置任何特殊选项。

对于以前的版本,最好的解决方案是在 ipdb 上显示绘图后使用 Matplotlib 中的 pause(n) 命令(其中 n 是秒数)。这是一个例子:

from matplotlib.pyplot import imshow, pause
import numpy as np
x = np.random.rand(4,5)
imshow(x)
pause(1)

【讨论】:

谢谢@Carlos。我已经确认这适用于plot()imshow()。这是一个几乎足够的临时解决方案。实现它的最佳方法是: (1) 将暂停时间设置为一个非常大的数字。 (2) 完成后,按 Ctrl-C 退出剧情并close() 它。当前的缺点是你不能同时检查多个图,除非你使用subplot() 我认为更新的问题现在在 github 中,请参见此处:Debugging: unable to see plots made with matplotlib · Issue #620 · spyder-ide/spyder【参考方案2】:

我发现您现在实际上可以使用 Spyder 在调试模式下绘图。这非常简单。

ipdb>pylab.plot(x,y)
ipdb>pylab.show()

......

【讨论】:

请提供所有版本号(Spyder、Python、图形后端库和版本(例如 Qt))。 此解决方案适用于 Spyder 4.1.2、Python 3.7、Qt 5.9.6。【参考方案3】:

您在导入pylab 时考虑过ion() 函数吗?这应该允许在pdb 中进行交互式绘图。

 import pylab
 import pdb
 pylab.ion()

 tst_xdata = [1,2,3,4,5,6]
 tst_ydata = [1,1,1,1,1,1]

 pylab.plot(tst_xdata,tst_ydata)
 pylab.draw()

 pdb.set_trace()
 for idx in range(3):

     tst_ydata = [elem+2 for elem in tst_ydata]
     pylab.plot(tst_xdata,tst_ydata)
     pylab.draw()

 pylab.show()

以上在我的机器上运行(Ubuntu 11.04、Python 2.7、SciPy bersion 0.8.0),甚至在 Eclipse 中使用 PyDev 运行。

【讨论】:

我认为 OP 希望在调试模式下运行 pylab,而不是 .py 文件中已有的 pylab 命令。 正如@user1914692所说。

以上是关于如何在 Spyder(或任何其他调试器)的 ipdb 调试器中强制 Matplotlib 进行绘制?的主要内容,如果未能解决你的问题,请参考以下文章

从其他文件夹导入模块:如何在 Spyder 或 PyCharm 中显示函数参数?

如何使用spyder调试python代码

如何在 Python 中使用 Spyder 进行高效调试?

使用 Spyder 调试远程 python 文件

Python开发环境Spyder安装方法

在调试python期间,Spyder在变量资源管理器中不显示类实例变量