Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

matplotlib: deliberately block code execution pending a GUI event

Is there some way that I can get matplotlib to block code execution pending a matplotlib.backend_bases.Event?

I've been working on some classes for interactively drawing lines and polygons inside matplotlib figures, following these examples. What I'd really like to do is block execution until I'm done editing my polygon, then get the final positions of the vertices - if you're familiar with MATLAB, I'm basically trying to replicate the position = wait(roihandle) syntax, for example here.

I suppose I could set some class attribute of my interactive polygon object when a keypress occurs, then repeatedly poll the object in my script to see if the event has occurred yet, but I was hoping there would be a nicer way.

like image 385
ali_m Avatar asked Jan 14 '13 20:01

ali_m


People also ask

Is PLT show () blocking?

show() and plt. draw() are unnecessary and / or blocking in one way or the other.

What GUI does matplotlib use?

Matplotlib is a plotting library for the Python programming language and its numerical mathematics extension NumPy. It provides an object-oriented API for embedding plots into applications using general-purpose GUI toolkits like Tkinter, wxPython, Qt, or GTK.

How do you stop a plot in Python?

Use the block = False inside show : plt.

What is interactive mode matplotlib?

Matplotlib can be used in an interactive or non-interactive modes. In the interactive mode, the graph display gets updated after each statement. In the non-interactive mode, the graph does not get displayed until explicitly asked to do so.


1 Answers

Well, that was easier than I thought it would be! For those who are interested I found a solution using figure.canvas.start_event_loop() and figure.canvas.stop_event_loop().

Here's a simple example:

from matplotlib import pyplot as plt

class FigEventLoopDemo(object):

    def __init__(self):

        self.fig, self.ax = plt.subplots(1, 1, num='Event loop demo')
        self.clickme = self.ax.text(0.5, 0.5, 'click me',
                                    ha='center', va='center',
                                    color='r', fontsize=20, picker=10)

        # add a callback that triggers when the text is clicked
        self.cid = self.fig.canvas.mpl_connect('pick_event', self.on_pick)

        # start a blocking event loop
        print("entering a blocking loop")
        self.fig.canvas.start_event_loop(timeout=-1)

    def on_pick(self, event):

        if event.artist is self.clickme:

            # exit the blocking event loop
            self.fig.canvas.stop_event_loop()
            print("now we're unblocked")
like image 101
ali_m Avatar answered Oct 21 '22 03:10

ali_m