Question

I use iPython notebook a lot together with matplotlib and whilst there are lots of cases when I am happy it automatically displays the images when I call imshow() there are moments when I would like to prevent that behavior.

Specifically I am looping over a very large array and generate a figure in matplotlib for each element which should be saved to disk. As part of that figure creation I have to call imshow() to draw an existing image (in my case the screenshot of a map) to the axis to later on draw additional material on top of that. Whenever I call imshow as part of the process the final figure is displayed inline in iPython notebook, how can I prevent that?

My code looks something like this:

import matplotlib as plt
fig = plt.pyplot.figure(figsize=(20,20))
im2 = plt.pyplot.imread('/some/dir/fancy-map.png')

# Magic to calculate points, x_min etc.

fig.clf()
ax = fig.gca(xlim=(x_min, x_max), ylim=(y_min, y_max))
ax.imshow(im2, extent=(4, 4.5746, 42.5448, 43.3791), aspect=1.5)
raster = ax.imshow(points, vmin = 0, vmax=maxval, extent=(x_min, x_max, y_min, y_max), aspect=1.5, origin='lower')
fig.colorbar(raster)
ax.set_title('coordinates plot')

fig.savefig("fancy-annotated-map.png", bbox_inches=0)
Was it helpful?

Solution

Try moving this into a function, and at the start of the function do pylab.ioff() and at the end return to pylab.ion():

# Obvs add arguments so you can pass in your data and plot choices.
def make_img():
    pylab.ioff()

    import matplotlib as plt
    fig = plt.pyplot.figure(figsize=(20,20))
    im2 = plt.pyplot.imread('/some/dir/fancy-map.png')

    # Magic to calculate points, x_min etc.

    fig.clf()
    ax = fig.gca(xlim=(x_min, x_max), ylim=(y_min, y_max))
    ax.imshow(im2, extent=(4, 4.5746, 42.5448, 43.3791), aspect=1.5)
    raster = ax.imshow(points, 
                       vmin = 0, 
                       vmax=maxval, 
                       extent=(x_min, x_max, y_min, y_max), 
                       aspect=1.5, 
                       origin='lower')
    fig.colorbar(raster)
    ax.set_title('coordinates plot')
    fig.savefig("fancy-annotated-map.png", bbox_inches=0)

    pylab.ion()
  1. This assumes you are using the function within IPython only, or else that pylab is always imported. Better wrap a try...except around it so the function can be used elsewhere.

  2. Have a look at the template for making your own IPython Magic functions (the % or %% function calls, like %cpaste). A nice approach to this would be to create your own magic, like %imnoshow or something, that wraps just the part that invokes imshow, so that you do in-line handling of imshow output without having to see the output. Since your question doesn't deal with a general plot interface, but rather this specific one, I won't try to implement this here, but hopefully the link above should be enough that you can implement something if you need to.

  3. Another approach is to follow the instructions for setting up your own IPython configuration environment, including having some particular .py file full of your own imports and helper class definitions, etc. Then place your own special plotting functions there so that they are loaded at start up and are available at global scope in IPython. I highly recommend this one for a few reasons: (a) you can actually write unit tests for your own helper functions and even easily have then tested every time you launch IPython if you wish! (b) This lets you more easily version control and encapsulate the logic of the helper functions you need often. (c) You get the benefit of the function "just being there" without needing to make it a magic function or import it later.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top