Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit ed5c016

Browse files
committed
Make Grouper return siblings in the order in which they have been seen.
1 parent f1bf554 commit ed5c016

File tree

3 files changed

+38
-31
lines changed

3 files changed

+38
-31
lines changed

lib/matplotlib/axes/_base.py

Lines changed: 7 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3915,26 +3915,20 @@ def format_coord(self, x, y):
39153915
return "x={} y={}".format(
39163916
"???" if x is None else self.format_xdata(x),
39173917
"???" if y is None else self.format_ydata(y))
3918-
x_twins = []
3919-
y_twins = []
3920-
# Retrieve twins in the order of self.figure.axes to sort tied zorders (which is
3921-
# the common case) by the order in which they are added to the figure.
3922-
for ax in self.figure.axes:
3923-
if ax in twins:
3924-
if ax is self or ax._sharex is self or self._sharex is ax:
3925-
x_twins.append(ax)
3926-
if ax is self or ax._sharey is self or self._sharey is ax:
3927-
y_twins.append(ax)
39283918
get_zorder = attrgetter("zorder")
3929-
x_twins.sort(key=get_zorder)
3930-
y_twins.sort(key=get_zorder)
3919+
x_twins = sorted([ax for ax in twins
3920+
if ax is self or ax._sharex is self or self._sharex is ax],
3921+
key=get_zorder)
3922+
y_twins = sorted([ax for ax in twins
3923+
if ax is self or ax._sharey is self or self._sharey is ax],
3924+
key=get_zorder)
39313925
screen_xy = self.transData.transform((x, y))
39323926
return "x={} y={}".format(
39333927
" / ".join(
39343928
ax.format_xdata(ax.transData.inverted().transform(screen_xy)[0])
39353929
for ax in y_twins),
39363930
" / ".join(
3937-
ax.format_xdata(ax.transData.inverted().transform(screen_xy)[1])
3931+
ax.format_ydata(ax.transData.inverted().transform(screen_xy)[1])
39383932
for ax in x_twins))
39393933

39403934
def minorticks_on(self):

lib/matplotlib/cbook.py

Lines changed: 29 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -783,21 +783,27 @@ class Grouper:
783783
"""
784784

785785
def __init__(self, init=()):
786-
self._mapping = weakref.WeakKeyDictionary(
787-
{x: weakref.WeakSet([x]) for x in init})
786+
self._count = itertools.count()
787+
# For each item, we store (order_in_which_item_was_seen, group_of_item), which
788+
# lets __iter__ and get_siblings return items in the order in which they have
789+
# been seen.
790+
self._mapping = weakref.WeakKeyDictionary()
791+
for x in init:
792+
if x not in self._mapping:
793+
self._mapping[x] = (next(self._count), weakref.WeakSet([x]))
788794

789795
def __getstate__(self):
790796
return {
791797
**vars(self),
792798
# Convert weak refs to strong ones.
793-
"_mapping": {k: set(v) for k, v in self._mapping.items()},
799+
"_mapping": {k: (i, set(v)) for k, (i, v) in self._mapping.items()},
794800
}
795801

796802
def __setstate__(self, state):
797803
vars(self).update(state)
798804
# Convert strong refs to weak ones.
799805
self._mapping = weakref.WeakKeyDictionary(
800-
{k: weakref.WeakSet(v) for k, v in self._mapping.items()})
806+
{k: (i, weakref.WeakSet(v)) for k, (i, v) in self._mapping.items()})
801807

802808
def __contains__(self, item):
803809
return item in self._mapping
@@ -810,25 +816,32 @@ def join(self, a, *args):
810816
"""
811817
Join given arguments into the same set. Accepts one or more arguments.
812818
"""
813-
mapping = self._mapping
814-
set_a = mapping.setdefault(a, weakref.WeakSet([a]))
815-
816-
for arg in args:
817-
set_b = mapping.get(arg, weakref.WeakSet([arg]))
819+
m = self._mapping
820+
try:
821+
_, set_a = m[a]
822+
except KeyError:
823+
_, set_a = m[a] = (next(self._count), weakref.WeakSet([a]))
824+
for b in args:
825+
try:
826+
_, set_b = m[b]
827+
except KeyError:
828+
_, set_b = m[b] = (next(self._count), weakref.WeakSet([b]))
818829
if set_b is not set_a:
819830
if len(set_b) > len(set_a):
820831
set_a, set_b = set_b, set_a
821832
set_a.update(set_b)
822833
for elem in set_b:
823-
mapping[elem] = set_a
834+
i, _ = m[elem]
835+
m[elem] = (i, set_a)
824836

825837
def joined(self, a, b):
826838
"""Return whether *a* and *b* are members of the same set."""
827-
return (self._mapping.get(a, object()) is self._mapping.get(b))
839+
return (self._mapping.get(a, (None, object()))[1]
840+
is self._mapping.get(b, (None, object()))[1])
828841

829842
def remove(self, a):
830843
"""Remove *a* from the grouper, doing nothing if it is not there."""
831-
set_a = self._mapping.pop(a, None)
844+
_, set_a = self._mapping.pop(a, (None, None))
832845
if set_a:
833846
set_a.remove(a)
834847

@@ -838,14 +851,14 @@ def __iter__(self):
838851
839852
The iterator is invalid if interleaved with calls to join().
840853
"""
841-
unique_groups = {id(group): group for group in self._mapping.values()}
854+
unique_groups = {id(group): group for _, group in self._mapping.values()}
842855
for group in unique_groups.values():
843-
yield [x for x in group]
856+
yield sorted(group, key=self._mapping.__getitem__)
844857

845858
def get_siblings(self, a):
846859
"""Return all of the items joined with *a*, including itself."""
847-
siblings = self._mapping.get(a, [a])
848-
return [x for x in siblings]
860+
_, siblings = self._mapping.get(a, (None, [a]))
861+
return sorted(siblings, key=self._mapping.get)
849862

850863

851864
class GrouperView:

lib/matplotlib/tests/test_cbook.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -594,9 +594,9 @@ class Dummy:
594594
for o in objs:
595595
assert o in mapping
596596

597-
base_set = mapping[objs[0]]
597+
_, base_set = mapping[objs[0]]
598598
for o in objs[1:]:
599-
assert mapping[o] is base_set
599+
assert mapping[o][1] is base_set
600600

601601

602602
def test_flatiter():

0 commit comments

Comments
 (0)