如何在 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 进行绘制?的主要内容,如果未能解决你的问题,请参考以下文章