Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to set timeout to pyplot.show() in matplotlib?

I am using python's matplotlib to draw figures.

I want to draw a figure with a timeout, say 3 seconds, and the window will close to move on the code.

I have known that pyplot.show() will create a blocking window with unlimited timeout; pyplot.show(block=False) or pyplot.draw() will make the window non-blocking. But what I want is let the code block for some seconds.

I have come up an idea that I might use an event handler or something, but still not really clear how to solve this. Is there any simple and elegant solution?

Suppose my code is like the following:

Draw.py:

import matplotlib.pyplot as plt

#Draw something
plt.show() #Block or not?
like image 434
Ting Yi Shih Avatar asked May 21 '15 04:05

Ting Yi Shih


2 Answers

Here's a simple example where I have created a timer to set your timeout and performed closing of window plot.close() in the callback function of the timer. Start the timer before plot.show() and after three seconds timer invokes close_event() and then continues with the rest of the code.

import matplotlib.pyplot as plt

def close_event():
    plt.close() #timer calls this function after 3 seconds and closes the window 

fig = plt.figure()
timer = fig.canvas.new_timer(interval = 3000) #creating a timer object and setting an interval of 3000 milliseconds
timer.add_callback(close_event)

plt.plot([1,2,3,4])
plt.ylabel('some numbers')

timer.start()
plt.show()
print("I am doing something else")

Hope that was helpful.

like image 178
Deepa Avatar answered Sep 27 '22 23:09

Deepa


This did not work for me on Mac OSX.

Looks like there are two issues:

  1. Calling plt.close() is not enough to exit the program sys.exit() works.

  2. The scheduled function seems to be called at startup. This results in a display time of zero. The window pops and disappears at the same time. Using state in the callback that treats the first call differently solves this problem. An instance of a class with the special method __call__() is a good approach for such a stateful callable.

This works for me:

from __future__ import print_function

import sys

import matplotlib.pyplot as plt


class CloseEvent(object):

    def __init__(self):
        self.first = True

    def __call__(self):
        if self.first:
            self.first = False
            return
        sys.exit(0)


fig = plt.figure()
timer = fig.canvas.new_timer(interval=3000)
timer.add_callback(CloseEvent())


plt.plot([1,2,3,4])
plt.ylabel('some numbers')

timer.start()
plt.show()
print("Am doing something else")
like image 30
Mike Müller Avatar answered Sep 27 '22 23:09

Mike Müller