1

I tend to switch back & forth between Jupyter notebooks and the Wing IDE for debugging code. What I love about the Jupyter notebook is that I can run a cell and generate a sequence of images, with code like this:

import matplotlib.pyplot as plt
for i in range(10):
    ...do stuff...
    plt.plot(image)
    plt.show()

All the images end up nicely one after another in the jupyter cell output region, and can be easily reviewed by scrolling through that region.

Often though I want to go into the debugger to write new code or debug something, and I have not found a good mechanism to do something similar.

Any suggestions how to go about this ?

One option would be to write a function that writes all images to disk and then just view those with a photo viewing application, but I wonder if there is another way.

Arjaan Buijk
  • 1,306
  • 16
  • 18
  • Not what you were asking, but spyder provides a cell-like execution model, and inline plots in the jupyter widget. – mdurant Apr 22 '17 at 01:31

2 Answers2

0

Probably the thing to do is to use wingdbstub so you can debug in the context of Jupyter. This is described in detail at http://wingware.com/doc/howtos/jupyter -- the limitation is you can't debug code in the .ipynb file, but you can put most things into .py files.

Stephan
  • 144
  • 4
0

I figured a way to do it that works pretty nice:

  • use a non-interactive back-end to avoid images from popping up
  • replace all calls to plt.show() with own function my_plt_show(), in which:

    • call to plt.show()
    • save each fig to a scratch dir, make sure to close the fig.
    • write a file 'all.html' in that scratch dir that will display the images. This is the all.html to write:

    <html> <img src="img_0000.jpg" /> <br /> <img src="img_0001.jpg" /> <br /> <img src="img_0002.jpg" /> <br /> <img src="img_0003.jpg" /> <br />

  • after running or while debugging, just keep that all.html file open in a browser, and it behaves almost like the output of a jupyter cell.

Here my example code:

I_AM_IN_JUPYTER = False
SCRATCH_IMAGE_DIR = 'C:\\Work\\ScratchImages'
SCRATCH_IMAGE_NUM = 0

if I_AM_IN_JUPYTER:
    get_ipython().magic('matplotlib inline')
else:
    # use non-interactive back-end to avoid images from popping up
    # See: http://stackoverflow.com/questions/9622163/save-plot-to-image-file-instead-of-displaying-it-using-matplotlib-so-it-can-be
    from matplotlib import use
    use('Agg') 

# function to show a plot or write it to disk
def my_plt_show():
    global I_AM_IN_JUPYTER, SCRATCH_IMAGE_NUM, f_html
    plt.show()
    if I_AM_IN_JUPYTER == False:
        # at start
        if SCRATCH_IMAGE_NUM == 0:
            # clean out the scratch image dir
            files = glob.glob(SCRATCH_IMAGE_DIR+'\\*')
            for f in files:
                os.remove(f)  
            # open 'all.html' that displays all the images written
            f_html = open(SCRATCH_IMAGE_DIR+'\\all.html', 'w')
            f_html.write('<html>\n')

        # save all images to a scratch dir
        fname = 'img_{:04d}.jpg'.format(SCRATCH_IMAGE_NUM)
        plt.savefig(SCRATCH_IMAGE_DIR+'\\'+fname)
        fig = plt.gcf() # get reference to the current figure
        plt.close(fig)  # and close it
        f_html.write('<img src="'+fname+'" /> <br />\n') 
        f_html.flush() # flush it directly to disk, for debug purposes.        
        SCRATCH_IMAGE_NUM += 1    
Arjaan Buijk
  • 1,306
  • 16
  • 18