-
-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Include child Axes inaxes calculation #25050
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
Conversation
This makes InsetAxes count for this field, and allows widgets to work in them. Fixes matplotlib#25030
As an example, I took the code from """
Illustrate the figure and axes enter and leave events by changing the
frame colors on enter and leave
"""
import matplotlib.pyplot as plt
def enter_axes(event):
print('enter_axes', event.inaxes)
event.inaxes.patch.set_facecolor('yellow')
event.canvas.draw()
def leave_axes(event):
print('leave_axes', event.inaxes)
event.inaxes.patch.set_facecolor('white')
event.canvas.draw()
def enter_figure(event):
print('enter_figure', event.canvas.figure)
event.canvas.figure.patch.set_facecolor('red')
event.canvas.draw()
def leave_figure(event):
print('leave_figure', event.canvas.figure)
event.canvas.figure.patch.set_facecolor('grey')
event.canvas.draw()
fig, ax = plt.subplots()
fig.suptitle('mouse hover over figure or axes to trigger events')
ax.set_label('Level 0')
for i in range(4):
ax = ax.inset_axes([0.2, 0.2, 0.6, 0.6])
ax.set_label(f'Level {i+1}')
fig.canvas.mpl_connect('figure_enter_event', enter_figure)
fig.canvas.mpl_connect('figure_leave_event', leave_figure)
fig.canvas.mpl_connect('axes_enter_event', enter_axes)
fig.canvas.mpl_connect('axes_leave_event', leave_axes)
plt.show() If you mouse over, then you will see the outer |
It wouldn't seem that you want to say you left the axes if you didn't leave the axes? I'm a little unclear of the use case here - do we want inset axes to have widgets in them? Not clear what the interactive logic is here, particularly as an inset axes doesn't have to be on top of the parent at all. Is there a reason we only check if the mouse is in an axes versus over a GUI element? |
In general I think axes_enter_event/axes_leave_event are rather poorly specified, exactly because it's unclear what should happen with overlapping axes. FWIW I would just get rid of axes_enter_event and axes_leave_event, and just hook to motion_notify_event, something like from matplotlib import pyplot as plt
def on_motion(event):
inaxes = event.inaxes # Depends on the actual inaxes semantics, of course.
for ax in axs:
ax.patch.set_facecolor("w")
if inaxes:
inaxes.patch.set_facecolor("y")
event.canvas.draw() # Could draw only if a change was actually made.
axs = []
fig, ax = plt.subplots()
ax.set_label('Level 0')
axs.append(ax)
for i in range(4):
ax = ax.inset_axes([0.2, 0.2, 0.6, 0.6])
ax.set_label(f'Level {i+1}')
axs.append(ax)
fig.canvas.mpl_connect('motion_notify_event', on_motion)
plt.show() |
I think #25555 may be a more general fix for the original issue, although it does not try to address what axes_{enter,leave}_event means in the presence of overlapping axes (again, I think that was not a really well-defined API to start with...). |
Yes, I thought that might be the case when I first saw that PR, but did not try it out. |
The original issue was fixed by #25555. While we should work out semantics for |
PR Summary
This makes
InsetAxes
count for this field, and allows widgets to work in them.Now, one question is that
inaxes
now is the innermost Axes only. That meansaxes_leave_event
is triggered for a parentAxes
when entering the child. Is that the behaviour that's desired? If we instead want this to only trigger when completely outside the parentAxes
, we'd have to do something like makeinaxes
a list (or a private-but-related field if we don't want to change API.)Fixes #25030
PR Checklist
Documentation and Tests
pytest
passes)Release Notes
.. versionadded::
directive in the docstring and documented indoc/users/next_whats_new/
.. versionchanged::
directive in the docstring and documented indoc/api/next_api_changes/
next_whats_new/README.rst
ornext_api_changes/README.rst