1

I have a for loop, in which I create and show a matplotlib figure. I also have a nested function (def onClick) which handles what happens when I click on the figure.

E.g.

for i in list:
    fig, ax = plt.subplots(1)
    plt.plot(data)

    def onClick(event):
        #doSomething = True

    cid = fig.canvas.mpl_connect('button_press_event', onclick)

    plt.show()

I want to be able to continue the for loop to its next iteration after, say, 6 clicks. I can't put the continue statement in the onClick function as it is not part of the for loop..

Any help would be appreciated.

GarethPrice
  • 1,072
  • 2
  • 14
  • 25

1 Answers1

1

First, plt.show() gets called once (see here on Stackoverflow and here on the Matplotlib mailing list). That's simply how Matplotlib is intended to be used. You prepare your plots and then plt.show() is the last line in the script.

But what if we want to show and interact with more than one plot? The trick is to prepare the plots ahead of time and still call plt.show() once at the end. Here's an example that uses the onclick event like in your code. It cycles through a few plots and then stops at the end. You'll have to rearrange your code a bit to save the results of whatever is going on in the for loop.

import numpy as np
import matplotlib.pyplot as plt

# prepare some pretty plots
stuff_to_plot = []
for i in range(10):
    stuff_to_plot.append(np.random.rand(10))

fig = plt.figure()
ax = fig.add_subplot(111)

coord_index = 0
plot_index = 0
def onclick(event):
    # get the index variables at global scope
    global coord_index
    if coord_index != 6:
        print 'button=%d, x=%d, y=%d, xdata=%f, ydata=%f'%(
            event.button, event.x, event.y, event.xdata, event.ydata)
        coord_index += 1
    else:
        coord_index = 0
        global plot_index
        # if we have more to plot, clear the plot and plot something new
        if plot_index < len(stuff_to_plot):
            plt.cla()
            ax.plot(stuff_to_plot[plot_index])
            plt.draw()
            plot_index += 1

cid = fig.canvas.mpl_connect('button_press_event', onclick)

# plot something before fist click
ax.plot(stuff_to_plot[plot_index])
plot_index += 1
plt.show()
Community
  • 1
  • 1
Praxeolitic
  • 22,455
  • 16
  • 75
  • 126
  • Thanks. Is it really that bad if I call show() more than once? That part is working fine at the moment, I just need to continue the for loop after six clicks. – GarethPrice Jun 23 '14 at 01:41
  • Praxeolitoc, it works when I close the window manually to skip to the next loop, I guess you mean it won't work if I do it automatically? – GarethPrice Jun 23 '14 at 01:48
  • 1
    Actually that surprises me. For me, once I call plt.show() and close out the subsequent calls are ignored. If that works for you and it's convenient, you might as well use it so long as you're aware that on some machines it might not work. – Praxeolitic Jun 23 '14 at 02:07