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

26 投票
3 回答
12694 浏览
提问于 2025-04-16 23:42

编辑

很遗憾,目前这件事是做不到的。我发现这是一个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 个回答

2

你有没有想过在导入 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 时也能运行。

5

我发现现在可以在调试模式下使用Spyder进行绘图了。这其实非常简单。

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

......

16

(这里是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)

撰写回答