[Matplotlib-users] Widget event issue #5812
Enkhbayar Erdenee
enkhee.data at gmail.com
Fri Jan 8 03:07:29 EST 2016
Thank you for taking time. I have changed the code according to your advice
and it works well. Now I have a clear understanding how to use pyplot and
widgets of matplotlib. Thank you again, your advice helped me a lot :)
On Fri, Jan 8, 2016 at 12:29 PM, Thomas Caswell <tcaswell at gmail.com> wrote:
> There is something a bit sutble going on here, see the following code:
>
> import matplotlib.pyplot as plt
> from six.moves import range
> import sys
>
> from matplotlib.widgets import RectangleSelector
> from matplotlib.widgets import Button
>
>
> def main_window(im):
> ref_holder = dict()
>
> def open_figure(event):
> ax = event.inaxes
> if ax is None:
> # Occurs when a region not in an axis is clicked...
> return
> for i in range(len(event.canvas.figure.axes)):
> if event.canvas.figure.axes[i] is ax:
> ret = show_new_figure(im)
> ref_holder['last interactive'] = ret
>
> fig, ax = plt.subplots()
>
> # some code which locates subplots
> # show images on subplots
> show_image(ax, im)
>
> fig.canvas.mpl_connect('button_press_event', open_figure)
> plt.show()
>
> return fig, ax
>
>
> def show_image(ax, im):
> ax.cla()
> ax.imshow(im, cmap='gray', interpolation='nearest')
>
>
> def show_new_figure(im):
> fig, ax = plt.subplots(figsize=(10, 10))
>
> class Btn(object):
> def save(self, event):
> fig.canvas.manager.toolbar.save_figure()
>
> def close(self, event):
> plt.close(fig)
>
> def exit(self, event):
> sys.exit()
>
> callback = Btn()
>
> ax.imshow(im, cmap='Reds', interpolation='nearest')
>
> axSave = plt.axes([0.5, 0.01, 0.1, 0.075])
> axClose = plt.axes([0.39, 0.01, 0.1, 0.075])
> axExit = plt.axes([0.6, 0.01, 0.1, 0.075])
>
> btnSave = Button(axSave, 'Save')
> btnSave.on_clicked(callback.save)
> btnClose = Button(axClose, 'Close')
> btnClose.on_clicked(callback.close)
> btnExit = Button(axExit, 'Exit')
> btnExit.on_clicked(callback.exit)
>
> # draw rectangle
> def line_select_callback(eclick, erelease):
> 'eclick and erelease are the press and release events'
> x1, y1 = eclick.xdata, eclick.ydata
> x2, y2 = erelease.xdata, erelease.ydata
> print("X, Y points: (%3.2f, %3.2f) --> (%3.2f, %3.2f)" %
> (x1, y1, x2, y2))
>
> rs = RectangleSelector(ax, line_select_callback,
> drawtype='box', useblit=True,
> button=[1, 3],
> minspanx=5, minspany=5,
> rectprops=dict(facecolor='blue',
> edgecolor='blue',
> alpha=1, fill=False),
> spancoords='pixels')
> rs.set_active(True)
>
> return rs, btnSave, btnClose, btnExit
>
>
> The critical bit is that the `show_new_figure` function is returning the
> `widget` objects and `open_figure` is stashing them in a local dictionary.
> What is happening is that without holding on to a reference to the widget
> objects they get garbage collected. By design, the callback registries
> only hold on to a weak-ref (that is a reference that will not prevent
> garbage collection if it is the last reference left), so if you do not keep
> a reference to the widgets, the get garbage collections and hence do not
> exist to get the click events. This is documented in the widget class
> docstring (ex
> http://matplotlib.org/api/widgets_api.html#matplotlib.widgets.Button)
>
> Tom
>
> On Thu, Jan 7, 2016 at 9:52 PM Enkhbayar Erdenee <enkhee.data at gmail.com>
> wrote:
>
>> Hello
>>
>> I have an issue on widget events. I have created a figure which contains
>> several subplots. When click on one of the subplots, it shows another
>> figure. This new figure contains button and rectangle selector widgets.
>> Until this it works fine. Problem is nothing happens if I click on the
>> buttons or draw rectangle on this new figure. It works well (i mean button
>> onclick, line_select_callback events raise ), if I just create figure not
>> after click the subplots. I do not know what I am doing wrong. Please help
>> me.
>>
>> By the way, I am using:
>> matplotlib.*version* : '1.4.3'
>> matplotlib.get_backend() : Qt4Agg
>> python: 2.7.10 | Anaconda 2.3.0 (64-bit)
>>
>>
>> Here is the some part of code that I having problem:
>>
>>
>> import sys
>>
>> import cv2
>>
>> from matplotlib.widgets import RectangleSelector
>>
>> import matplotlib.pyplot as plt
>>
>> from matplotlib.widgets import Button
>>
>>
>> def main_window():
>>
>>
>> def open_figure(event):
>>
>> ax = event.inaxes
>>
>> if ax is None:
>>
>> # Occurs when a region not in an axis is clicked...
>>
>> return
>>
>> for i in xrange(len(event.canvas.figure.axes)):
>>
>> if event.canvas.figure.axes[i] is ax:
>>
>> plt.ion()
>>
>> # Show clicked image on new figure
>>
>> show_new_figure(im)
>>
>>
>> fig = plt.figure(1)
>>
>>
>>
>> # some code which locates subplots
>>
>> # show images on subplots
>>
>> show_image(im)
>>
>>
>>
>> fig.canvas.mpl_connect('button_press_event', open_figure)
>>
>> plt.show()
>>
>>
>> def show_image(im):
>>
>> im = im[:, :, (2, 1, 0)]
>>
>> plt.cla()
>>
>> plt.imshow(im)
>>
>> plt.axis('off')
>>
>> plt.draw()
>>
>> # plt.show()
>>
>>
>> def show_new_figure(im):
>>
>>
>> class Btn:
>>
>> def save(self, event):
>>
>> plt.close()
>>
>> def close(self, event):
>>
>> plt.close()
>>
>> def exit(self, event):
>>
>> sys.exit()
>>
>>
>> callback = Btn()
>>
>>
>> im = im[:, :, (2, 1, 0)]
>>
>> fig2, ax = plt.subplots(figsize=(10, 10))
>>
>> plt.cla()
>>
>> plt.imshow(im)
>>
>>
>> axSave = plt.axes([0.5, 0.01, 0.1, 0.075])
>>
>> axClose = plt.axes([0.39, 0.01, 0.1, 0.075])
>>
>> axExit = plt.axes([0.6, 0.01, 0.1, 0.075])
>>
>>
>> btnSave = Button(axSave, 'Save')
>>
>> btnSave.on_clicked(callback.save)
>>
>> btnClose = Button(axClose, 'Close')
>>
>> btnClose.on_clicked(callback.close)
>>
>> btnExit = Button(axExit, 'Exit')
>>
>> btnExit.on_clicked(callback.exit)
>>
>>
>> # draw rectangle
>>
>> def line_select_callback(eclick, erelease):
>>
>> 'eclick and erelease are the press and release events'
>>
>> x1, y1 = eclick.xdata, eclick.ydata
>>
>> x2, y2 = erelease.xdata, erelease.ydata
>>
>> print ("X, Y points: (%3.2f, %3.2f) --> (%3.2f, %3.2f)" % (x1,
>> y1, x2, y2))
>>
>>
>> rs = RectangleSelector(ax, line_select_callback,
>>
>> drawtype='box', useblit=True,
>>
>> button=[1, 3],
>>
>> minspanx=5, minspany=5,
>>
>> rectprops=dict(facecolor='blue',
>> edgecolor='blue',
>>
>> alpha=1, fill=False),
>>
>> spancoords='pixels')
>>
>> rs.set_active(True)
>>
>>
>> plt.axis('off')
>>
>> plt.show()
>>
>>
>> Thank you for consideration.
>> _______________________________________________
>> Matplotlib-users mailing list
>> Matplotlib-users at python.org
>> https://mail.python.org/mailman/listinfo/matplotlib-users
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/matplotlib-users/attachments/20160108/a5b90bc4/attachment-0001.html>
More information about the Matplotlib-users
mailing list