3

I am trying to retrieve an array as an output from a matplotlib event:

import numpy as np
import matplotlib.pyplot as plt

def onclick(event):
    global points
    try:
        points = np.append(points,[[event.xdata,event.ydata]],axis=0)
    except NameError:
        points = np.array([[event.xdata,event.ydata]])
    ax.plot(points[:,0],points[:,1],'o')
    plt.draw()

fig = plt.figure()
ax = fig.add_subplot(111)
ax.set_xlim((0,10))
ax.set_ylim((0,10))
plt.gcf().canvas.mpl_connect('button_press_event',onclick)
plt.show()

Even tough I have declared "points" to be global,

print(points)

returns a NameError. How can I retrieve "points"? Thank you for any help!!

1
  • Why not just wrap it all up in a class. This is standard practice for Tkinter GUIs and matplotlib GUIs. Then you could assign to self.points. Commented Apr 1, 2014 at 14:45

1 Answer 1

4

You cannot just declare a variable as global, you have to create it initially. The following code should work as you expect.

import numpy as np
import matplotlib.pyplot as plt

points = []

def onclick(event):
    global points
    points.append([event.xdata, event.ydata])

    ax.plot(event.xdata, event.ydata,'o')
    plt.draw()

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

ax.set_xlim((0, 10))
ax.set_ylim((0, 10))

plt.gcf().canvas.mpl_connect('button_press_event', onclick)

plt.show()

Shown below is a plot after I clicked 5 times.

Example plot

EDIT

Instead of plotting a new marker every single time you add a point, you could instead modify the plot object you already have. Like below.

import matplotlib.pyplot as plt

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

ax.set_xlim((0, 10))
ax.set_ylim((0, 10))

points = []

line, = ax.plot(points, 'o--')

def onclick(event):
    global points
    points.append([event.xdata, event.ydata])

    line.set_data(zip(*points))
    plt.draw()

plt.gcf().canvas.mpl_connect('button_press_event', onclick)

plt.show()

This will plot points once and then everytime the user clicks on the plot it will modify the line object and re-draw it.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks a lot! That solves it very simply. And nice suggestions too.
I think the code on top doesn't really answer the question, because it doesn't test if "points" now exists in the global scope. I tested a similar approach, and still don't know how to put define global variable from a click event...

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.