1

I'm using Python 3.6 in jupyter notebook. plt.close does not close plot. I tried with plt.ion() also and many other ways.

I want to display image, then wait for pause or input() and then remove the previous image and show the new one.

import matplotlib.pyplot as plt
from time import sleep
from scipy import eye

plt.imshow(eye(3))
plt.show()
sleep(1)
plt.close()
klapeyron
  • 502
  • 7
  • 18
  • 2
    Please have a look at [this](https://stackoverflow.com/questions/28269157/plotting-in-a-non-blocking-way-with-matplotlib). Your script is pauses when you call `plt.show()`, which means that nothing else can happen before you close the figure manually. – Thomas Kühn Jan 31 '19 at 13:46
  • @ThomasKühn when I'm adding plt.close() to example u gave to me, it does not change smth. – klapeyron Jan 31 '19 at 14:21
  • The point was not to leave out `plt.show()`, the point was that `plt.show()` *blocks* the script. You could use non-blocking mode, i.e. `plt.show(block=True)`, but you should be aware how that changes the functionality of matplotlib, hence the link. If you *do* use non-blocking mode, you will need some other measure of keeping the script alive ... – Thomas Kühn Jan 31 '19 at 14:24
  • @ThomasKühn I can display images after pauses or inputs. But these images all are on my input canvas. I wish to display only one image which is the last in that action sequence. So: the pause happened, the last image displayed, next pause happened, that image removed and displayed a new one. – klapeyron Jan 31 '19 at 14:34
  • 1
    I answered before reading the comments, I fear that what OP wants is something entirely different than what the question asks for. @Nikytee can you please clarify inside the question what *exactly* you are trying to achieve? – ImportanceOfBeingErnest Jan 31 '19 at 14:43
  • So I think what OP wants is to get rid of the figure that is produced in the output section of a jupyter notebook and replace it with a new figure repeatedly (probably using the inline backend). Is that correct? – ImportanceOfBeingErnest Jan 31 '19 at 15:09
  • @ImportanceOfBeingErnest yes. – klapeyron Jan 31 '19 at 15:11

2 Answers2

1

Here is an example that shows a sequence of plots, each for one second. Essential are the commants plt.show(block = False) and plt.pause(1) instead of sleep(1):

import numpy as np
import matplotlib.pyplot as plt

def show_image(n):
    fig, ax = plt.subplots()
    x = np.linspace(0,1,100)
    y = x**n
    ax.plot(x,y, label = 'x**{}'.format(n))
    ax.legend()
    plt.show(block=False)
    plt.pause(1)
    plt.close(fig)



for i in range(10):
    show_image(i)
Thomas Kühn
  • 9,412
  • 3
  • 47
  • 63
  • I replaced plt.pause(1) on sleep(1) due an error "name 'time' is not defined". But figures still do not close. Sry, I dont know whats going on. Maybe I will check versions of matplotlib. – klapeyron Jan 31 '19 at 14:57
  • @Nikytee did you try to run the example I posted? It works perfectly for me. – Thomas Kühn Jan 31 '19 at 14:59
  • Yes. Except "plt.pause(1)" string which I replaced due to the mistake. – klapeyron Jan 31 '19 at 15:03
  • I updated libraries and there is no "name 'time' is not defined" error now. But figures from your code still do not close. – klapeyron Jan 31 '19 at 15:18
  • 1
    @Nikytee ok, then this must be special in jupyter notebook. I unfortunately don't have any experience with that. – Thomas Kühn Jan 31 '19 at 15:20
0

If I understand correctly, what you want is to show a plot, wait 1 second, then let it close automatically.

This would be achieved as follows.

import matplotlib.pyplot as plt
from scipy import eye

plt.imshow(eye(3))

def show_and_close(sec):
    timer = plt.gcf().canvas.new_timer(interval=sec*1000)
    timer.add_callback(lambda : plt.close())
    timer.single_shot = True
    timer.start()
    plt.show()

show_and_close(1)
ImportanceOfBeingErnest
  • 321,279
  • 53
  • 665
  • 712