[Matplotlib-users] selecting points inside plot

Jody Klymak jklymak at uvic.ca
Tue Sep 5 13:36:17 EDT 2017


OK, I think you want the equivalent of matlab’s

```
plot(something)
x,y = ginput(‘Click the figure’)
plot(x, y)
```

*and* you want it to execute in an interactive session in `ipython` 
(spyder)

I don’t think you can do that, though there may be some new widgets 
that will let it happen these days.

Historically, it is better to think of any graphical interaction as a 
separate program.   If you are willing to do that, then plotting the 
data as you click is very simple:

```python

import matplotlib
matplotlib.use('Qt5Agg')

import matplotlib.pyplot as plt
import numpy as np

class Picker(object):

     def __init__(self, ax=None):
         self.x = np.array([])
         self.y = np.array([])
         self.ax = ax
         self.dots, = ax.plot(1, 1, marker='o')
         self.dots.set_xdata(self.x)
         self.dots.set_ydata(self.y)
         self.fig = self.ax.get_figure()

     def process_key(self, event):
         print("Key:", event.key)

     def process_button(self, event):
         print("Button:", event.x, event.y, event.xdata, event.ydata, 
event.button)
         self.x = np.append(self.x, event.xdata)
         self.y = np.append(self.y, event.ydata)
         self.dots.set_xdata(self.x)
         self.dots.set_ydata(self.y)
         plt.draw()

     def get_x(self):
         return self.x

     def get_y(self):
         return self.y

fig, ax = plt.subplots(1, 1)
picker = Picker(ax=ax)
fig.canvas.mpl_connect('key_press_event', picker.process_key)
fig.canvas.mpl_connect('button_press_event', picker.process_button)
plt.show()

print(picker.x)  #
print(picker.get_x())  # the same
print(picker.get_x().mean()) # returns the mean of x.
print(picker.get_y())
print(picker.get_y().mean())

```

You save the above as a file (`mypicker.py`) and in `ipython` you 
execute `run mypicker.py`.  Note that after you have executed it, 
`picker` is still in your workspace to access.

I hope that helps.

Jody



On 5 Sep 2017, at 6:33, Jean-Philippe Grivet wrote:

> Thank you Benjamin and Jody for your sugestions. Due to my scanty 
> knwledge of Python,
> I unfortunately can't get these programs to do what I want.
> Referring to Jody's code, the statement "print(x)" is executed only 
> once, upon
> lauching the program. Then, the various xdata values are stored in x 
> but nothing more
> happens, until I close the graphic window. This termintes execution. 
> If I issue print(x)
> in the console, I recover the values of interest. My attempts to plot 
> a dot where the
> button was clicked have failed.
> Ben's code behaves similarly, except that it starts by attempting to 
> compute the
> average of some undefined values.
> Can this poor performance be due to the fact that I work inside Spyder 
> ?
> I am sorry that I keep trying your patience but I will be grateful for 
> any
> suggestion.
> Sincetrely,
> Jean-Philippe
>> |import matplotlib matplotlib.use('Qt5Agg') import matplotlib.pyplot 
>> as plt import numpy as np class Picker(object): def __init__(self): 
>> self.x = np.array([]) self.y = np.array([]) def process_key(self, 
>> event): print("Key:", event.key) def process_button(self, event): 
>> print("Button:", event.x, event.y, event.xdata, event.ydata, 
>> event.button) self.x = np.append(self.x, event.xdata) self.y = 
>> np.append(self.y, event.ydata) def get_x(self): return self.x def 
>> get_y(self): return self.y fig, ax = plt.subplots(1, 1) picker = 
>> Picker() fig.canvas.mpl_connect('key_press_event', 
>> picker.process_key) fig.canvas.mpl_connect('button_press_event', 
>> picker.process_button) plt.show() print(picker.x) # 
>> print(picker.get_x()) # the same print(picker.get_x().mean()) # 
>> returns the mean of x. print(picker.get_y()) 
>> print(picker.get_y().mean()) |
>>
>> On 2 Sep 2017, at 18:08, Benjamin Root wrote:
>>
>>     If you assign a class method as the callbacks, such as
>>     process_button(self, event), then that method could save the
>>     relevant values to itself. I show how to do this in my book (as
>>     well as the global approach, too).
>>
>>     Cheers!
>>     Ben Root
>>
>>     On Sat, Sep 2, 2017 at 10:30 AM, Jody Klymak <jklymak at uvic.ca
>>     <mailto:jklymak at uvic.ca>> wrote:
>>
>>         Hi Jean-Philippe
>>
>>         There may be a fancier way, but you can just declare a global
>>         in |process_button| to pass the value to a global variable.
>>
>>         Cheers, Jody
>>
>>         |import matplotlib.pyplot as plt x = [] def 
>> process_key(event):
>>         print("Key:", event.key) def process_button(event): global x
>>         print("Button:", event.x, event.y, event.xdata, event.ydata,
>>         event.button) x += [event.xdata] fig, ax = plt.subplots(1, 1)
>>         fig.canvas.mpl_connect('key_press_event', process_key)
>>         fig.canvas.mpl_connect('button_press_event', process_button)
>>         plt.show() print(x) |
>>
>
>
> ---
> L'absence de virus dans ce courrier électronique a été vérifiée 
> par le logiciel antivirus Avast.
> https://www.avast.com/antivirus


-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20170905/12e4a8ce/attachment.html>


More information about the Matplotlib-users mailing list