New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[Bug]: Exception not handled in widgetlock() #23324
Comments
Good first issue because there is no API choices here, but medium because it requires understanding locks in the UI and making sure that the pan/zoom mode are left in a good (non-selected) state when this fails. |
In my code, I do the following to deactivate zoom and pan when entering the selector: if self.fig.canvas.toolbar.mode == backend_bases._Mode.PAN:
self.fig.canvas.toolbar.pan() # pan() and zoom() are toggles
elif self.fig.canvas.toolbar.mode == backend_bases._Mode.ZOOM:
self.fig.canvas.toolbar.zoom() where it works fine, I just want to be sure that the user does not enter zoom or pan while in the selector. self.fig.canvas.toolbar._current_action = '' # deselect pan/zoom buttons - see backend_nbagg otherwise, the button and greyed even though the action is not activated. (did not check other backends...) |
I did a little bit of tinkering and came up with a very naive fix (my very first contribution!). Would you take a look at my PR please? I still haven't figured out how to prevent pan and zoom from being toggled in the toolbar. |
I was able to test the PR in jupyter notebook (the environment I need the feature) the following code passes successfuly: # This code show how you can temporary disable the zoom/pan modes
# when using an interactive selector
# In[1]:
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.widgets as mwidgets
from matplotlib import backend_bases
import numpy as np
# In[2]:
matplotlib._version.version # check version
# In[3]:
get_ipython().run_line_magic('matplotlib', 'notebook')
# In[4]:
fig, ax = plt.subplots()
x = np.linspace(0,10,100)
plt.plot(x, np.sin(x) )
rect_selected = [0,0]
def on_select(mini, maxi):
"selector callback, returns xmin, xmax, in data unit"
global rect_selected
rect_selected = [mini, maxi]
# In[5]:
rect = mwidgets.RectangleSelector(ax, on_select, button=3, interactive=True)
print("deactivating Zoom/Pan modes, but Home and History are still available")
if fig.canvas.toolbar.mode == backend_bases._Mode.PAN:
fig.canvas.toolbar.pan() # pan() and zoom() are toggles
elif fig.canvas.toolbar.mode == backend_bases._Mode.ZOOM:
fig.canvas.toolbar.zoom()
fig.canvas.toolbar._current_action = '' # deselect pan/zoom buttons - see backend_nbagg
# then get the lock
fig.canvas.widgetlock(rect)
print ('Now select a zone of the plot with the right mouse button')
# In[7]:
# show selected entries
print(rect_selected[0],'\n',rect_selected[1])
# In[8]:
# clear, release the lock and delete
rect.set_visible(False)
fig.canvas.widgetlock.release(rect)
del rect as you see it works fine when in |
Bug summary
( This bug was originally issued in ipympl: matplotlib/ipympl#471 )
I want to use a selector matplotlib.widgets.RectangleSelector , it is incompatible with zoom and pan
So I try to call widgetlock to prevent user from using zoom when the selector is active, hoping that the zoom or pan tools will not be blocked.
This does not work, but crashes rather.
Code for reproduction
Actual outcome
if you then hit the zoom or pan matplotlib button, which also try to get the lock, you get
Expected outcome
The lock is grabbed by the Selector, when zoom it tries to grab the lock, an exception is raised which is the normal behaviour of the lock, however the zoom tool should handle the exception and give-up.
Additional information
100% reproducible in my set-up
Operating system
Ubuntu 20.04
Matplotlib Version
3.3.2
Matplotlib Backend
Qt5Agg
Python version
3.8.5
Jupyter version
N/A
Installation
conda
The text was updated successfully, but these errors were encountered: