[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