8000 Merge pull request #5682 from tacaswell/fix_twin_remove · matplotlib/matplotlib@f9e405e · GitHub
[go: up one dir, main page]

Skip to content

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit f9e405e

Browse files
committed
Merge pull request #5682 from tacaswell/fix_twin_remove
Fix twin remove
2 parents 4a705d1 + f0a32b3 commit f9e405e

File tree

4 files changed

+122
-3
lines changed

4 files changed

+122
-3
lines changed

lib/matplotlib/cbook.py

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1669,7 +1669,7 @@ class Grouper(object):
16691669
False
16701670
16711671
"""
1672-
def __init__(self, init=[]):
1672+
def __init__(self, init=()):
16731673
mapping = self._mapping = {}
16741674
for x in init:
16751675
mapping[ref(x)] = [ref(x)]
@@ -1721,6 +1721,14 @@ def joined(self, a, b):
17211721
except KeyError:
17221722
return False
17231723

1724+
def remove(self, a):
1725+
self.clean()
1726+
1727+
mapping = self._mapping
1728+
seta = mapping.pop(ref(a), None)
1729+
if seta is not None:
1730+
seta.remove(ref(a))
1731+
17241732
def __iter__(self):
17251733
"""
17261734
Iterate over each of the disjoint sets as a list.

lib/matplotlib/figure.py

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -916,7 +916,7 @@ def add_axes(self, *args, **kwargs):
916916

917917
self._axstack.add(key, a)
918918
self.sca(a)
919-
a._remove_method = lambda ax: self.delaxes(ax)
919+
a._remove_method = self.__remove_ax
920920
self.stale = True
921921
a.stale_callback = _stale_figure_callback
922922
return a
@@ -1006,11 +1006,37 @@ def add_subplot(self, *args, **kwargs):
10061006

10071007
self._axstack.add(key, a)
10081008
self.sca(a)
1009-
a._remove_method = lambda ax: self.delaxes(ax)
1009+
a._remove_method = self.__remove_ax
10101010
self.stale = True
10111011
a.stale_callback = _stale_figure_callback
10121012
return a
10131013

1014+
def __remove_ax(self, ax):
1015+
def _reset_loc_form(axis):
1016+
axis.set_major_formatter(axis.get_major_formatter())
1017+
axis.set_major_locator(axis.get_major_locator())
1018+
axis.set_minor_formatter(axis.get_minor_formatter())
1019+
axis.set_minor_locator(axis.get_minor_locator())
1020+
1021+
def _break_share_link(ax, grouper):
1022+
siblings = grouper.get_siblings(ax)
1023+
if len(siblings) > 1:
1024+
grouper.remove(ax)
1025+
for last_ax in siblings:
1026+
if ax is last_ax:
1027+
continue
1028+
return last_ax
1029+
return None
1030+
1031+
self.delaxes(ax)
1032+
last_ax = _break_share_link(ax, ax._shared_y_axes)
1033+
if last_ax is not None:
1034+
_reset_loc_form(last_ax.yaxis)
1035+
1036+
last_ax = _break_share_link(ax, ax._shared_x_axes)
1037+
if last_ax is not None:
1038+
_reset_loc_form(last_ax.xaxis)
1039+
10141040
def clf(self, keep_observers=False):
10151041
"""
10161042
Clear the figure.

lib/matplotlib/tests/test_axes.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4086,11 +4086,57 @@ def test_shared_scale():
40864086
assert_equal(ax.get_yscale(), 'linear')
40874087
assert_equal(ax.get_xscale(), 'linear')
40884088

4089+
40894090
@cleanup
40904091
def test_violin_point_mass():
40914092
"""Violin plot should handle point mass pdf gracefully."""
40924093
plt.violinplot(np.array([0, 0]))
40934094

4095+
4096+
@cleanup
4097+
def test_remove_shared_axes():
4098+
4099+
def _helper_x(ax):
4100+
ax2 = ax.twinx()
4101+
ax2.remove()
4102+
ax.set_xlim(0, 15)
4103+
r = ax.xaxis.get_major_locator()()
4104+
assert r[-1] > 14
4105+
4106+
def _helper_y(ax):
4107+
ax2 = ax.twiny()
4108+
ax2.remove()
4109+
ax.set_ylim(0, 15)
4110+
r = ax.yaxis.get_major_locator()()
4111+
assert r[-1] > 14
4112+
4113+
# test all of the ways to get fig/ax sets
4114+
fig = plt.figure()
4115+
ax = fig.gca()
4116+
yield _helper_x, ax
4117+
yield _helper_y, ax
4118+
4119+
fig, ax = plt.subplots()
4120+
yield _helper_x, ax
4121+
yield _helper_y, ax
4122+
4123+
fig, ax_lst = plt.subplots(2, 2, sharex='all', sharey='all')
4124+
ax = ax_lst[0][0]
4125+
yield _helper_x, ax
4126+
yield _helper_y, ax
4127+
4128+
fig = plt.figure()
4129+
ax = fig.add_axes([.1, .1, .8, .8])
4130+
yield _helper_x, ax
4131+
yield _helper_y, ax
4132+
4133+
fig, ax_lst = plt.subplots(2, 2, sharex='all', sharey='all')
4134+
ax = ax_lst[0][0]
4135+
orig_xlim = ax_lst[0][1].get_xlim()
4136+
ax.remove()
4137+
ax.set_xlim(0, 5)
4138+
assert assert_array_equal(ax_lst[0][1].get_xlim(), orig_xlim)
4139+
40944140
if __name__ == '__main__':
40954141
import nose
40964142
import sys

lib/matplotlib/tests/test_cbook.py

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
from __future__ import (absolute_import, division, print_function,
22
unicode_literals)
3+
import itertools
4+
from weakref import ref
35

46
from matplotlib.externals import six
57

@@ -376,3 +378,40 @@ def test_step_fails():
376378
np.arange(12))
377379
assert_raises(ValueError, cbook._step_validation,
378380
np.arange(12), np.arange(3))
381+
382+
383+
def test_grouper():
384+
class dummy():
385+
pass
386+
a, b, c, d, e = objs = [dummy() for j in range(5)]
387+
g = cbook.Grouper()
388+
g.join(*objs)
389+
assert set(list(g)[0]) == set(objs)
390+
assert set(g.get_siblings(a)) == set(objs)
391+
392+
for other in objs[1:]:
393+
assert g.joined(a, other)
394+
395+
g.remove(a)
396+
for other in objs[1:]:
397+
assert not g.joined(a, other)
398+
399+
for A, B in itertools.product(objs[1:], objs[1:]):
400+
assert g.joined(A, B)
401+
402+
403+
def test_grouper_private():
404+
class dummy():
405+
pass
406+
objs = [dummy() for j in range(5)]
407+
g = cbook.Grouper()
408+
g.join(*objs)
409+
# reach in and touch the internals !
410+
mapping = g._mapping
411+
412+
for o in objs:
413+
assert ref(o) in mapping
414+
415+
base_set = mapping[ref(objs[0])]
416+
for o in objs[1:]:
417+
assert mapping[ref(o)] is base_set

0 commit comments

Comments
 (0)
0