Skip to content

Commit d2289c9

Browse files
committed
fix figure.clf and subplot_adjust
1 parent e1c9ec5 commit d2289c9

File tree

3 files changed

+166
-60
lines changed

3 files changed

+166
-60
lines changed

lib/matplotlib/figure.py

+89-47
Original file line numberDiff line numberDiff line change
@@ -172,77 +172,81 @@ def __init__(self, left=None, bottom=None, right=None, top=None,
172172
wspace=None, hspace=None):
173173
"""
174174
All dimensions are fractions of the figure width or height.
175-
Defaults are given by :rc:`figure.subplot.[name]`.
175+
Defaults are given by :rc:`figure.subplot.*`.
176176
177177
Parameters
178178
----------
179-
left : float
179+
left : float, optional
180180
The left side of the subplots of the figure.
181181
182-
right : float
182+
right : float, optional
183183
The right side of the subplots of the figure.
184184
185-
bottom : float
185+
bottom : float, optional
186186
The bottom of the subplots of the figure.
187187
188-
top : float
188+
top : float, optional
189189
The top of the subplots of the figure.
190190
191-
wspace : float
191+
wspace : float, optional
192192
The amount of width reserved for space between subplots,
193193
expressed as a fraction of the average axis width.
194194
195-
hspace : float
195+
hspace : float, optional
196196
The amount of height reserved for space between subplots,
197197
expressed as a fraction of the average axis height.
198198
"""
199199
self.validate = True
200200
self.update(left, bottom, right, top, wspace, hspace)
201201

202+
def __repr__(self):
203+
return ("SubplotParams(left={}, bottom={}, right={}, top={}, "
204+
"wspace={}, hspace={})").format(
205+
self.left, self.bottom, self.right, self.top,
206+
self.wspace, self.hspace)
207+
202208
def update(self, left=None, bottom=None, right=None, top=None,
203-
wspace=None, hspace=None):
204-
"""
205-
Update the dimensions of the passed parameters. *None* means unchanged.
206-
"""
207-
thisleft = getattr(self, 'left', None)
208-
thisright = getattr(self, 'right', None)
209-
thistop = getattr(self, 'top', None)
210-
thisbottom = getattr(self, 'bottom', None)
211-
thiswspace = getattr(self, 'wspace', None)
212-
thishspace = getattr(self, 'hspace', None)
213-
214-
self._update_this('left', left)
215-
self._update_this('right', right)
216-
self._update_this('bottom', bottom)
217-
self._update_this('top', top)
218-
self._update_this('wspace', wspace)
219-
self._update_this('hspace', hspace)
220-
221-
def reset():
222-
self.left = thisleft
223-
self.right = thisright
224-
self.top = thistop
225-
self.bottom = thisbottom
226-
self.wspace = thiswspace
227-
self.hspace = thishspace
209+
wspace=None, hspace=None, rc_default=False):
210+
"""
211+
Update the dimensions of the passed parameters. *None* means
212+
unchanged if the attribute is set and *rc_default* is *False*, and
213+
:rc:`figure.subplot.*` otherwise.
214+
"""
215+
216+
varDict=dict(left=left, bottom=bottom, right=right, top=top,
217+
wspace=wspace, hspace=hspace)
218+
oldVarDict={key: getattr(self, key, None) for key in varDict.keys()}
228219

220+
self._update(varDict, rc_default)
229221
if self.validate:
230222
if self.left >= self.right:
231-
reset()
223+
self._update(oldVarDict)
232224
raise ValueError('left cannot be >= right')
233225

234226
if self.bottom >= self.top:
235-
reset()
227+
self._update(oldVarDict)
236228
raise ValueError('bottom cannot be >= top')
237229

238-
def _update_this(self, s, val):
239-
if val is None:
240-
val = getattr(self, s, None)
241-
if val is None:
242-
key = 'figure.subplot.' + s
243-
val = rcParams[key]
230+
def _update(self, varDict, rc_default=None):
231+
for att, value in varDict.items():
232+
if value is None:
233+
if not rc_default:
234+
value = getattr(self, att, None)
235+
if value is None:
236+
key = 'figure.subplot.' + att
237+
value = rcParams[key]
244238

245-
setattr(self, s, val)
239+
setattr(self, att, value)
240+
241+
def get_subplot_params(self):
242+
"""
243+
Returns
244+
-------
245+
A dictionary with the subplot parameters
246+
"""
247+
subplot_params = self.__dict__.copy()
248+
del subplot_params['validate']
249+
return subplot_params
246250

247251

248252
class Figure(Artist):
@@ -1400,8 +1404,11 @@ def clf(self, keep_observers=False):
14001404
"""
14011405
Clear the figure.
14021406
1403-
Set *keep_observers* to True if, for example,
1404-
a gui widget is tracking the axes in the figure.
1407+
Parameters
1408+
---------
1409+
keep_observers : bool, optional
1410+
Set *keep_observers* to True if, for example,
1411+
a gui widget is tracking the axes in the figure.
14051412
"""
14061413
self.suppressComposite = None
14071414
self.callbacks = cbook.CallbackRegistry()
@@ -1420,6 +1427,7 @@ def clf(self, keep_observers=False):
14201427
self.texts = []
14211428
self.images = []
14221429
self.legends = []
1430+
self.subplotpars.update(rc_default=True)
14231431
if not keep_observers:
14241432
self._axobservers = []
14251433
self._suptitle = None
@@ -1908,13 +1916,47 @@ def colorbar(self, mappable, cax=None, ax=None, use_gridspec=True, **kw):
19081916
return cb
19091917

19101918
def subplots_adjust(self, left=None, bottom=None, right=None, top=None,
1911-
wspace=None, hspace=None):
1919+
wspace=None, hspace=None, rc_default=False):
19121920
"""
1913-
Update the :class:`SubplotParams` with *kwargs* (defaulting to rc when
1914-
*None*) and update the subplot locations.
1921+
Tune the subplots layout by updating the subplots parameters and
1922+
the subplot locations.
1923+
1924+
All dimensions are fractions of the figure width or height.
1925+
1926+
Parameters
1927+
----------
1928+
left : float, optional
1929+
The left side of the subplots of the figure.
19151930
1931+
right : float, optional
1932+
The right side of the subplots of the figure.
1933+
1934+
bottom : float, optional
1935+
The bottom of the subplots of the figure.
1936+
1937+
top : float, optional
1938+
The top of the subplots of the figure.
1939+
1940+
wspace : float, optional
1941+
The amount of width reserved for space between subplots,
1942+
expressed as a fraction of the average axis width.
1943+
1944+
hspace : float, optional
1945+
The amount of height reserved for space between subplots,
1946+
expressed as a fraction of the average axis height.
1947+
1948+
rc_default : bool, optional
1949+
Determine the defaults. *True* and the default is taken from
1950+
:rc:`figure.subplot.*`, *False* and the value is unchanged.
1951+
1952+
Notes
1953+
-----
1954+
The subplots parameters are stored in the `~.Figure` attribute
1955+
``subplotpars`` as a `~.SubplotParams` object.
19161956
"""
1917-
self.subplotpars.update(left, bottom, right, top, wspace, hspace)
1957+
1958+
self.subplotpars.update(left, bottom, right, top, wspace,
1959+
hspace, rc_default)
19181960
for ax in self.axes:
19191961
if not isinstance(ax, SubplotBase):
19201962
# Check if sharing a subplots axis

lib/matplotlib/pyplot.py

+35-13
Original file line numberDiff line numberDiff line change
@@ -1201,25 +1201,47 @@ def twiny(ax=None):
12011201

12021202

12031203
def subplots_adjust(left=None, bottom=None, right=None, top=None,
1204-
wspace=None, hspace=None):
1204+
wspace=None, hspace=None, rc_default=False):
12051205
"""
1206-
Tune the subplot layout.
1206+
Tune the subplots layout by updating the subplots parameters and
1207+
the subplot locations.
12071208
1208-
The parameter meanings (and suggested defaults) are::
1209+
All dimensions are fractions of the figure width or height.
12091210
1210-
left = 0.125 # the left side of the subplots of the figure
1211-
right = 0.9 # the right side of the subplots of the figure
1212-
bottom = 0.1 # the bottom of the subplots of the figure
1213-
top = 0.9 # the top of the subplots of the figure
1214-
wspace = 0.2 # the amount of width reserved for space between subplots,
1215-
# expressed as a fraction of the average axis width
1216-
hspace = 0.2 # the amount of height reserved for space between subplots,
1217-
# expressed as a fraction of the average axis height
1211+
Parameters
1212+
----------
1213+
left : float, optional
1214+
The left side of the subplots of the figure.
1215+
1216+
right : float, optional
1217+
The right side of the subplots of the figure.
1218+
1219+
bottom : float, optional
1220+
The bottom of the subplots of the figure.
1221+
1222+
top : float, optional
1223+
The top of the subplots of the figure.
1224+
1225+
wspace : float, optional
1226+
The amount of width reserved for space between subplots,
1227+
expressed as a fraction of the average axis width.
12181228
1219-
The actual defaults are controlled by the rc file
1229+
hspace : float, optional
1230+
The amount of height reserved for space between subplots,
1231+
expressed as a fraction of the average axis height.
1232+
1233+
rc_default : bool, optional
1234+
Determine the defaults. *True* and the default is taken from
1235+
:rc:`figure.subplot.*`, *False* and the value is unchanged.
1236+
1237+
Notes
1238+
-----
1239+
The subplots parameters are stored in the `~.Figure` attribute
1240+
``subplotpars`` as a `~.SubplotParams` object.
12201241
"""
1242+
12211243
fig = gcf()
1222-
fig.subplots_adjust(left, bottom, right, top, wspace, hspace)
1244+
fig.subplots_adjust(left, bottom, right, top, wspace, hspace, rc_default)
12231245

12241246

12251247
def subplot_tool(targetfig=None):

lib/matplotlib/tests/test_figure.py

+42
Original file line numberDiff line numberDiff line change
@@ -386,3 +386,45 @@ def test_fspath(fmt, tmpdir):
386386
# All the supported formats include the format name (case-insensitive)
387387
# in the first 100 bytes.
388388
assert fmt.encode("ascii") in file.read(100).lower()
389+
390+
391+
def test_clf_subplotpars():
392+
keys = ('left', 'right', 'bottom', 'top', 'wspace', 'hspace')
393+
rc_params = {key: plt.rcParams['figure.subplot.'+key] for key in keys}
394+
395+
fig = plt.figure(1)
396+
fig.subplots_adjust(left=0.1)
397+
fig.clf()
398+
assert fig.subplotpars.get_subplot_params() == rc_params
399+
400+
401+
def test_suplots_adjust_1():
402+
fig = plt.figure(1)
403+
wspace = 0
404+
fig.subplots_adjust(wspace=wspace)
405+
inDict = dict(left=0.1, right=0.7, bottom=0, top=0.9, hspace=0.05)
406+
fig.subplots_adjust(**inDict)
407+
inDict['wspace'] = wspace
408+
assert fig.subplotpars.get_subplot_params() == inDict
409+
410+
411+
def test_suplots_adjust_2():
412+
fig = plt.figure(1)
413+
fig.subplots_adjust(wspace=0)
414+
inDict = dict(left=0.1, right=0.7, bottom=0, top=0.9, hspace=0.05,
415+
rc_default=True)
416+
fig.subplots_adjust(**inDict)
417+
inDict['wspace'] = plt.rcParams['figure.subplot.wspace']
418+
del inDict['rc_default']
419+
assert fig.subplotpars.get_subplot_params() == inDict
420+
421+
422+
def test_suplots_adjust_plt():
423+
plt.figure(1)
424+
plt.subplots_adjust(wspace=0)
425+
inDict = dict(left=0.1, right=0.7, bottom=0, top=0.9, hspace=0.05,
426+
rc_default=True)
427+
plt.subplots_adjust(**inDict)
428+
inDict['wspace'] = plt.rcParams['figure.subplot.wspace']
429+
del inDict['rc_default']
430+
assert plt.gcf().subplotpars.get_subplot_params() == inDict

0 commit comments

Comments
 (0)