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

Skip to content

Commit a395083

Browse files
authored
Merge pull request #22138 from stanleyjs/subfigure-clear
Fix clearing subfigures
2 parents a2a1b0a + 5fe0e9d commit a395083

File tree

2 files changed

+124
-31
lines changed

2 files changed

+124
-31
lines changed

lib/matplotlib/figure.py

Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -913,6 +913,45 @@ def _break_share_link(ax, grouper):
913913
# Break link between any twinned axes
914914
_break_share_link(ax, ax._twinned_axes)
915915

916+
def clf(self, keep_observers=False):
917+
"""
918+
Clear the figure.
919+
920+
Parameters
921+
----------
922+
keep_observers: bool, default: False
923+
Set *keep_observers* to True if, for example,
924+
a gui widget is tracking the Axes in the figure.
925+
"""
926+
self.suppressComposite = None
927+
self.callbacks = cbook.CallbackRegistry()
928+
929+
# first clear the axes in any subfigures
930+
for subfig in self.subfigs:
931+
subfig.clf(keep_observers=keep_observers)
932+
self.subfigs = []
933+
934+
for ax in tuple(self.axes): # Iterate over the copy.
935+
ax.cla()
936+
self.delaxes(ax) # Remove ax from self._axstack.
937+
938+
self.artists = []
939+
self.lines = []
940+
self.patches = []
941+
self.texts = []
942+
self.images = []
943+
self.legends = []
944+
if not keep_observers:
945+
self._axobservers = cbook.CallbackRegistry()
946+
self._suptitle = None
947+
self._supxlabel = None
948+
self._supylabel = None
949+
950+
self.stale = True
951+
952+
# synonym for `clf`."""
953+
clear = clf
954+
916955
# Note: in the docstring below, the newlines in the examples after the
917956
# calls to legend() allow replacing it with figlegend() to generate the
918957
# docstring of pyplot.figlegend.
@@ -2801,40 +2840,13 @@ def set_figheight(self, val, forward=True):
28012840
self.set_size_inches(self.get_figwidth(), val, forward=forward)
28022841

28032842
def clf(self, keep_observers=False):
2804-
"""
2805-
Clear the figure.
2806-
2807-
Set *keep_observers* to True if, for example,
2808-
a gui widget is tracking the Axes in the figure.
2809-
"""
2810-
self.suppressComposite = None
2811-
self.callbacks = cbook.CallbackRegistry()
2812-
2813-
for ax in tuple(self.axes): # Iterate over the copy.
2814-
ax.cla()
2815-
self.delaxes(ax) # Remove ax from self._axstack.
2816-
2843+
# docstring inherited
2844+
super().clf(keep_observers=keep_observers)
2845+
# FigureBase.clf does not clear toolbars, as
2846+
# only Figure can have toolbars
28172847
toolbar = self.canvas.toolbar
28182848
if toolbar is not None:
28192849
toolbar.update()
2820-
self._axstack = _AxesStack()
2821-
self.artists = []
2822-
self.lines = []
2823-
self.patches = []
2824-
self.texts = []
2825-
self.images = []
2826-
self.legends = []
2827-
if not keep_observers:
2828-
self._axobservers = cbook.CallbackRegistry()
2829-
self._suptitle = None
2830-
self._supxlabel = None
2831-
self._supylabel = None
2832-
2833-
self.stale = True
2834-
2835-
def clear(self, keep_observers=False):
2836-
"""Clear the figure -- synonym for `clf`."""
2837-
self.clf(keep_observers=keep_observers)
28382850

28392851
@_finalize_rasterization
28402852
@allow_rasterization

lib/matplotlib/tests/test_figure.py

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -709,6 +709,87 @@ def test_removed_axis():
709709
fig.canvas.draw()
710710

711711

712+
def test_figure_clear():
713+
# we test the following figure clearing scenarios:
714+
fig = plt.figure()
715+
716+
# a) an empty figure
717+
fig.clear()
718+
assert fig.axes == []
719+
720+
# b) a figure with a single unnested axes
721+
ax = fig.add_subplot(111)
722+
fig.clear()
723+
assert fig.axes == []
724+
725+
# c) a figure multiple unnested axes
726+
axes = [fig.add_subplot(2, 1, i+1) for i in range(2)]
727+
fig.clear()
728+
assert fig.axes == []
729+
730+
# d) a figure with a subfigure
731+
gs = fig.add_gridspec(ncols=2, nrows=1)
732+
subfig = fig.add_subfigure(gs[0])
733+
subaxes = subfig.add_subplot(111)
734+
fig.clear()
735+
assert subfig not in fig.subfigs
736+
assert fig.axes == []
737+
738+
# e) a figure with a subfigure and a subplot
739+
subfig = fig.add_subfigure(gs[0])
740+
subaxes = subfig.add_subplot(111)
741+
mainaxes = fig.add_subplot(gs[1])
742+
743+
# e.1) removing just the axes leaves the subplot
744+
mainaxes.remove()
745+
assert fig.axes == [subaxes]
746+
747+
# e.2) removing just the subaxes leaves the subplot
748+
# and subfigure
749+
mainaxes = fig.add_subplot(gs[1])
750+
subaxes.remove()
751+
assert fig.axes == [mainaxes]
752+
assert subfig in fig.subfigs
753+
754+
# e.3) clearing the subfigure leaves the subplot
755+
subaxes = subfig.add_subplot(111)
756+
assert mainaxes in fig.axes
757+
assert subaxes in fig.axes
758+
subfig.clear()
759+
assert subfig in fig.subfigs
760+
assert subaxes not in subfig.axes
761+
assert subaxes not in fig.axes
762+
assert mainaxes in fig.axes
763+
764+
# e.4) clearing the whole thing
765+
subaxes = subfig.add_subplot(111)
766+
fig.clear()
767+
assert fig.axes == []
768+
assert fig.subfigs == []
769+
770+
# f) multiple subfigures
771+
subfigs = [fig.add_subfigure(gs[i]) for i in [0, 1]]
772+
subaxes = [sfig.add_subplot(111) for sfig in subfigs]
773+
assert all(ax in fig.axes for ax in subaxes)
774+
assert all(sfig in fig.subfigs for sfig in subfigs)
775+
776+
# f.1) clearing only one subfigure
777+
subfigs[0].clear()
778+
assert subaxes[0] not in fig.axes
779+
assert subaxes[1] in fig.axes
780+
assert subfigs[1] in fig.subfigs
781+
782+
# f.2) clearing the whole thing
783+
subfigs[1].clear()
784+
subfigs = [fig.add_subfigure(gs[i]) for i in [0, 1]]
785+
subaxes = [sfig.add_subplot(111) for sfig in subfigs]
786+
assert all(ax in fig.axes for ax in subaxes)
787+
assert all(sfig in fig.subfigs for sfig in subfigs)
788+
fig.clear()
789+
assert fig.subfigs == []
790+
assert fig.axes == []
791+
792+
712793
@mpl.style.context('mpl20')
713794
def test_picking_does_not_stale():
714795
fig, ax = plt.subplots()

0 commit comments

Comments
 (0)