[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