Skip to content

Navigation Menu

Sign in
Appearance settings

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 8864085

Browse filesBrowse 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
Copy full SHA for 8864085

File tree

Expand file treeCollapse file tree

2 files changed

+8
-10
lines changed
Filter options
Expand file treeCollapse file tree

2 files changed

+8
-10
lines changed

‎lib/matplotlib/_constrained_layout.py

Copy file name to clipboardExpand all lines: lib/matplotlib/_constrained_layout.py
+3-1Lines 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

Copy file name to clipboardExpand all lines: lib/matplotlib/_layoutgrid.py
+5-9Lines 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 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.