如何在Spyder (或其他调试器) 的ipdb调试中强制Matplotlib绘图?
编辑
很遗憾,目前这件事是做不到的。我发现这是一个Spyder中的bug。开发者们还在想办法解决这个问题。
目标
在调试代码时可视化数据(我也想用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。
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 版本 0.8.0)这个方法是有效的,甚至在使用 Eclipse 和 PyDev 时也能运行。
我发现现在可以在调试模式下使用Spyder进行绘图了。这其实非常简单。
ipdb>pylab.plot(x,y)
ipdb>pylab.show()
......
(这里是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)