8000 Let widgets better handle overlapping axes. · matplotlib/matplotlib@98e8d69 · GitHub
[go: up one dir, main page]

Skip to content

Commit 98e8d69

Browse files
committed
Let widgets better handle overlapping axes.
In general, using event.inaxes/event.xdata/event.ydata can be error-prone when there are overlapping axes, because only the topmost axes is the "in"-axes. In the specific case of widgets, in particular, we can instead check whether an event occurred over the axes and if so compute xdata/ydata accordingly. Doing so allows correct handling of widgets on axes for which there's also a twin axes on top of it. Changes in the tests (other than the change in test_span_selector, which tests the functionality here) ensure that the synthetic button presses indeed occur on top of the desired axes (previously, do_event would directly set event.inaxes and we'd just believe that "as is").
1 parent 7baa2b8 commit 98e8d69

File tree

2 files changed

+109
-102
lines changed

2 files changed

+109
-102
lines changed

lib/matplotlib/tests/test_widgets.py

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -645,6 +645,13 @@ def test_span_selector(ax, orientation, onmove_callback, kwargs):
645645
if onmove_callback:
646646
kwargs['onmove_callback'] = onmove
647647

648+
# While at it, also test that span selectors work in the presence of twin axes on
649+
# top of the axes that contain the selector. Note that we need to unforce the axes
650+
# aspect here, otherwise the twin axes forces the original axes' limits (to respect
651+
# aspect=1) which makes some of the values below go out of bounds.
652+
ax.set_aspect("auto")
653+
tax = ax.twinx()
654+
648655
tool = widgets.SpanSelector(ax, onselect, orientation, **kwargs)
649656
do_event(tool, 'press', xdata=100, ydata=100, button=1)
650657
# move outside of axis
@@ -927,7 +934,7 @@ def mean(vmin, vmax):
927934

928935
# Change span selector and check that the line is drawn/updated after its
929936
# value was updated by the callback
930-
press_data = [4, 2]
937+
press_data = [4, 0]
931938
move_data = [5, 2]
932939
release_data = [5, 2]
933940
do_event(span, 'press', xdata=press_data[0], ydata=press_data[1], button=1)
@@ -1035,7 +1042,7 @@ def test_TextBox(ax, toolbar):
10351042

10361043
assert submit_event.call_count == 2
10371044

1038-
do_event(tool, '_click')
1045+
do_event(tool, '_click', xdata=.5, ydata=.5) # Ensure the click is in the axes.
10391046
do_event(tool, '_keypress', key='+')
10401047
do_event(tool, '_keypress', key='5')
10411048

@@ -1634,7 +1641,8 @@ def test_polygon_selector_verts_setter(fig_test, fig_ref, draw_bounding_box):
16341641

16351642

16361643
def test_polygon_selector_box(ax):
1637-
# Create a diamond shape
1644+
# Create a diamond (adjusting axes lims s.t. the diamond lies within axes limits).
1645+
ax.set(xlim=(-10, 50), ylim=(-10, 50))
16381646
verts = [(20, 0), (0, 20), (20, 40), (40, 20)]
16391647
event_sequence = [
16401648
*polygon_place_vertex(*verts[0]),

0 commit comments

Comments
 (0)
0