26

EDIT

Unfortunately, at the moment this is not possible. I found out that it is a bug in Spyder. The developers are still figuring out how to approach this.


Goal

Visualize data while debugging code (and I want to use Spyder too!).

Attempt #1: Run foo.bar from IPython from Spyder

  • Create a file named foo.py with the following code:

    from ipdb import set_trace as st
    import matplotlib.pyplot as plt
    
    def bar():
        st()
    
  • While in IPython, type the following:

    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()
    

Plot remains in "frozen" state. If I exit debugger, plot updates. If I try to close the plot, IPython crashes. Obviously both undesirable, and neither lets me see the data while debugging.

Attempt #2: Run foo.bar from IPython from command line

  • Use same foo.py as in Attempt #1:
  • Open IPython from commandline:

    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()
    

Program shows plot as I expect. BUT I want to use Spyder.

Attempt #3: Run baz.bar from IPython from command line

  • Write baz.py:

    from ipdb import set_trace as st
    import matplotlib.pyplot as plt
    
    st()
    
  • Open IPython from commandline:

    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.
    

Then Spyder fully freezes.

Any suggestions?

Note #1: In my full code, I have many files and many functions, so mashing it all together in one script without functions is not viable.

Note #2: Using any matplotlib interactive command (e.g. ion(), interactive(True), etc.) had no effect.

Note #3: Spyder version 2.0.12, Python 2.6, matplotlib 1.0.1.

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
Peter D
  • 3,283
  • 4
  • 24
  • 23
  • `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)` – Peter D Aug 16 '11 at 16:45
  • `In [3]: matplotlib.get_backend() Out[3]: 'Qt4Agg'` – Peter D Aug 16 '11 at 17:00
  • Thanks, was able to change it to TkAgg. Same problem happened. `plt.plot()` created the figure, but white content (i.e. nothing written inside); `plt.show()` does nothing; `exit()` caused Spyder to freeze. – Peter D Aug 16 '11 at 17:19
  • @eryksun let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/2543/discussion-between-peter-d-and-eryksun) – Peter D Aug 16 '11 at 17:23
  • What version of matplotlib do you have? – dom_beau Aug 16 '11 at 17:11

3 Answers3

16

(Spyder maintainer here) Spyder 4.2.0, released on November 8/2020, supports the ability to work with interactive Matplotlib plots while debugging. That works out of the box, i.e. it doesn't require setting any special option.

For previous versions, the best solution is to use the pause(n) command from Matplotlib (where n is a number of seconds) after showing the plot on ipdb. Here is an example:

from matplotlib.pyplot import imshow, pause
import numpy as np
x = np.random.rand(4,5)
imshow(x)
pause(1)
Carlos Cordoba
  • 33,273
  • 10
  • 95
  • 124
  • 1
    Thanks @Carlos. I've confirmed that this works for `plot()` as well as `imshow()`. This is a near adequate temporary solution. The best way to implement it is to: **(1)** Set the pause time to a really large number. **(2)** When done, hit **Ctrl-C** to escape from the plot and `close()` it. The current shortcoming is that you cannot examine multiple plots simultaneously unless you use `subplot()` – Peter D Jan 20 '14 at 00:30
  • I think the updated issue is in github now, see here: [Debugging: unable to see plots made with matplotlib · Issue #620 · spyder-ide/spyder](https://github.com/spyder-ide/spyder/issues/620) – ollydbg23 Sep 26 '17 at 05:50
5

I found that you can actually plot in debug mode using Spyder now. It is surprisingly simple.

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

......

Andre Silva
  • 4,782
  • 9
  • 52
  • 65
Wang Yuan
  • 453
  • 1
  • 5
  • 8
2

Have you considered the ion() function when importing pylab? This should allow interactive plotting in 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()

The above works on my machine (Ubuntu 11.04, Python 2.7, SciPy bersion 0.8.0), even running in Eclipse with PyDev.

ely
  • 74,674
  • 34
  • 147
  • 228