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

Skip to content

Commit 8864085

Browse files
committed
Don't save parents in LayoutGrid
Internally, the parent is only used in `__init__`, so doesn't need to be saved as an attribute. Externally, the constrained layout code needs the parent only for subfigure margins, but we have the parent gridspec available directly to use. The `LayoutGrid` stores its children in a NumPy array, and saving the parent causes a reference cycle. Apparently having one reference in a C-level NumPy array causes Python to not realize it can garbage collect the cycle, causing all `LayoutGrid` and its children to leak.
1 parent b0d47f0 commit 8864085

File tree

2 files changed

+8
-10
lines changed

2 files changed

+8
-10
lines changed

lib/matplotlib/_constrained_layout.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -346,13 +346,15 @@ def make_layout_margins(layoutgrids, fig, renderer, *, w_pad=0, h_pad=0,
346346
"""
347347
for sfig in fig.subfigs: # recursively make child panel margins
348348
ss = sfig._subplotspec
349+
gs = ss.get_gridspec()
350+
349351
make_layout_margins(layoutgrids, sfig, renderer,
350352
w_pad=w_pad, h_pad=h_pad,
351353
hspace=hspace, wspace=wspace)
352354

353355
margins = get_margin_from_padding(sfig, w_pad=0, h_pad=0,
354356
hspace=hspace, wspace=wspace)
355-
layoutgrids[sfig].parent.edit_outer_margin_mins(margins, ss)
357+
layoutgrids[gs].edit_outer_margin_mins(margins, ss)
356358

357359
for ax in fig._localaxes:
358360
if not ax.get_subplotspec() or not ax.get_in_layout():

lib/matplotlib/_layoutgrid.py

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@ def __init__(self, parent=None, parent_pos=(0, 0),
3838
h_pad=None, w_pad=None, width_ratios=None,
3939
height_ratios=None):
4040
Variable = kiwi.Variable
41-
self.parent = parent
4241
self.parent_pos = parent_pos
4342
self.parent_inner = parent_inner
4443
self.name = name + seq_id()
@@ -57,12 +56,10 @@ def __init__(self, parent=None, parent_pos=(0, 0),
5756
if not isinstance(parent, LayoutGrid):
5857
# parent can be a rect if not a LayoutGrid
5958
# allows specifying a rectangle to contain the layout.
60-
self.parent = parent
6159
self.solver = kiwi.Solver()
6260
else:
63-
self.parent = parent
6461
parent.add_child(self, *parent_pos)
65-
self.solver = self.parent.solver
62+
self.solver = parent.solver
6663
# keep track of artist associated w/ this layout. Can be none
6764
self.artists = np.empty((nrows, ncols), dtype=object)
6865
self.children = np.empty((nrows, ncols), dtype=object)
@@ -100,7 +97,7 @@ def __init__(self, parent=None, parent_pos=(0, 0),
10097
# set these margins to zero by default. They will be edited as
10198
# children are filled.
10299
self.reset_margins()
103-
self.add_constraints()
100+
self.add_constraints(parent)
104101

105102
self.h_pad = h_pad
106103
self.w_pad = w_pad
@@ -130,11 +127,11 @@ def reset_margins(self):
130127
'leftcb', 'rightcb', 'bottomcb', 'topcb']:
131128
self.edit_margins(todo, 0.0)
132129

133-
def add_constraints(self):
130+
def add_constraints(self, parent):
134131
# define self-consistent constraints
135132
self.hard_constraints()
136133
# define relationship with parent layoutgrid:
137-
self.parent_constraints()
134+
self.parent_constraints(parent)
138135
# define relative widths of the grid cells to each other
139136
# and stack horizontally and vertically.
140137
self.grid_constraints()
@@ -168,12 +165,11 @@ def add_child(self, child, i=0, j=0):
168165
# np.ix_ returns the cross product of i and j indices
169166
self.children[np.ix_(np.atleast_1d(i), np.atleast_1d(j))] = child
170167

171-
def parent_constraints(self):
168+
def parent_constraints(self, parent):
172169
# constraints that are due to the parent...
173170
# i.e. the first column's left is equal to the
174171
# parent's left, the last column right equal to the
175172
# parent's right...
176-
parent = self.parent
177173
if not isinstance(parent, LayoutGrid):
178174
# specify a rectangle in figure coordinates
179175
hc = [self.lefts[0] == parent[0],

0 commit comments

Comments
 (0)